I’m experimenting with an API which returns acronym definitions. My site has 2 custom post types, ‘acronym’ and ‘definition’. I’m generating a random 2 – 3 letter string and feeding it to the API. The idea is that, if the API returns data, the randomly generated acronym is added as an ‘acronym’ post and the definitions are added as ‘definition’ posts. The definitions are then linked to the acronym via an ACF field. If the randomly generated acronym already exists as an ‘acronym’ post, then the definitions are simply created and assigned to that acronym post.
I’m running the code using the WP admin footer hook for testing purposes. Here’s a boiled down version of my code:
add_action('admin_footer', 'api_fetch');
function api_fetch(){
$length = rand(2, 3);
$randacro = '';
for ($i = 0; $i < $length; $i++) {
$randacro .= chr(rand(97, 122));
}
// Set the endpoint URL
$url = 'https://apiurl.com/xxxxxxxxx/' . $randacro . '&format=json';
// Initialize curl
$curl = curl_init($url);
// Set curl options
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json'
));
// Send the request and get the response
$response = curl_exec($curl);
// Close curl
curl_close($curl);
// Handle the response
if ($response) {
$resarray = json_decode($response);
echo '<div style="padding: 0 200px 50px;">Randomly generated acronym: ' . strtoupper($randacro) . '<br><br>';
if ( isset($resarray->result) ) {
if (post_exists(strtoupper($randacro))) {
$args = array(
'post_type' => 'acronym',
'post_title' => strtoupper($randacro),
'posts_per_page' => 1,
);
$query = new WP_Query( $args );
if ( $query->have_posts() ) {
$acro_id = $query->posts[0]->ID;
wp_reset_postdata();
}
} else {
$new_acro = array(
'post_title' => strtoupper(wp_strip_all_tags($randacro)),
'post_status' => 'publish',
'post_author' => 1,
'post_type' => 'acronym',
);
$acro_id = wp_insert_post( $new_acro );
}
if ($acro_id) {
echo 'Found/created acronym post: ID = ' . $acro_id . ' - Title = ' . get_the_title($acro_id) . '<br><br><pre>';
foreach($resarray->result as $result) {
print_r($result);
echo '<br><br>';
if (!is_string($result)) {
$def = $result->definition;
if ( get_post_status( $acro_id ) && !post_exists( $def ) ) {
$new_def = array(
'post_title' => wp_strip_all_tags($def),
'post_status' => 'publish',
'post_author' => 1,
'post_type' => 'definition',
);
$new_def_id = wp_insert_post( $new_def );
update_field('acronym', $acro_id, $new_def_id);
update_field('likes', '0', $new_def_id);
$defs_published++;
}
}
}
}
}
echo '</pre></div>';
} else {
echo '<div style="padding: 0 200px;">No response</div>';
}
}
The issue I’m having is that, when I refresh the page to run the code again after the code has created a new acronym, and it then finds an existing acronym, it’s assigning the definitions to the previously created new acronym. For example, this time that the code was run, it created the acronym post "VC" as it didn’t already exist:
I refreshed the page to run the code again, and the randomly generated acronym already exists as an ‘acronym’ post, but the definitions are being assigned to the previously created acronym post (shown as "Found/created acronym post"):
I’ve tried adding wp_reset_postdata()
and wp_reset_query()
throughout my code. I’ve tried setting the $acro_id
to null
at the beginning and end of the code and I’ve tried unsetting all the variables at the end of my code, but none of this has worked. Any ideas where I might be going wrong here?
2
Answers
There’s no search parameter
post_title
, it should be justtitle
.For some reason there’s no mention of this parameter in the official docs, but you can find it in the source file: https://github.com/WordPress/wordpress-develop/blob/6.2/src/wp-includes/class-wp-query.php#L631
In your case this was causing the issue, because you basically made query like this:
Which just gave you the latest added post.
During your foreach loop you can check for other definitions assigned to the $randacro. If it’s a new definition you can then post a new one using the update_field() function. Try incorporating this into your code.