I've used an adapted version of a csv import plugin for wordpress. It imports the csv to create and update posts. To update existing posts I've added an edit that finds the post id by title, then if it exists it overwrites, otherwise it creates a new post.
Problem is that it seems to not be very reliable! If I import the same csv several times it over-writes most of them but I get a few duplicates. Is there any way I can make this more reliable, or is there another way I can deal with duplicate posts?
main function for creating posts here
function create_post($data, $options) {
extract($options);
//edit 1 added here
global $wpdb;
//end
$data = array_merge($this->defaults, $data);
$type = $data['csv_post_type'] ? $data['csv_post_type'] : 'post';
$valid_type = (function_exists('post_type_exists') &&
post_type_exists($type)) || in_array($type, array('post', 'page'));
if (!$valid_type) {
$this->log['error']["type-{$type}"] = sprintf(
'Unknown post type "%s".', $type);
}
$new_post = array(
'post_title' => convert_chars($data['csv_post_title']),
'post_content' => wpautop(convert_chars($data['csv_post_post'])),
'post_status' => $opt_draft,
'post_type' => $type,
'post_date' => $this->parse_date($data['csv_post_date']),
'post_excerpt' => convert_chars($data['csv_post_excerpt']),
'post_name' => $data['csv_post_slug'],
'post_author' => $this->get_auth_id($data['csv_post_author']),
'tax_input' => $this->get_taxonomies($data),
'post_parent' => $data['csv_post_parent'],
);
// edit 2 here
$new_post['ID'] = $wpdb->get_var( "SELECT ID FROM $wpdb->posts WHERE post_title = '" . $data['csv_post_title'] . "'" );
// ends
// pages don't have tags or categories
if ('page' !== $type) {
$new_post['tags_input'] = $data['csv_post_tags'];
// Setup categories before inserting
$cats = $this->create_or_get_categories($data, $opt_cat);
$new_post['post_category'] = $cats['post'];
}
// edit 3
if(!empty($new_post['ID'])) {
$id = wp_update_post($new_post);
} else {
$id = wp_insert_post($new_post);
}
// ends
if ('page' !== $type && !$id) {
// cleanup new categories on failure
foreach ($cats['cleanup'] as $c) {
wp_delete_term($c, 'category');
}
}
return $id;
}
thanks
Fixed! I used the built in wordpress function, get_page_by_title . Here is the code I used to target the correct post.
if (!get_page_by_title( $bpp_title, 'OBJECT', 'publications')) {
$id = wp_insert_post($new_post);
} else {
$bpp_page = get_page_by_title( $bpp_title, 'OBJECT', 'publications');
$new_post['ID'] = $bpp_page->ID;
$id = wp_update_post($new_post);
}
Related
I am using WordPress to develop a website and I am hitting a roadblock. How do I save the radio button values from an html form into an advanced custom field? The options that I have show up in the admin but the checked option is not picked. I want to change the color of an object according to the value picked. I am also getting the name and a brief description and that stores in the admin database no problem. I am using wp_insert_post() to submit the form because I want to display the results after submitting.
if(isset($_POST['new_post']) == '1') {
$current_post_author_id = get_the_author_meta( 'ID' );
$post_title = wp_strip_all_tags($_POST['postTitle']);
$post_category = $_POST['review'];
$post_content = wp_strip_all_tags($_POST['postContent']);
$postid = get_the_ID();
$postStarOne = $POST['rateOne'];
$postStarTwo = $POST['rateTwo'];
$postStarThree = $POST['rateThree'];
$postStarFour = $POST['rateFour'];
$postStarFive = $POST['rateFive'];
//$custom_meta = get_post_meta($post->ID, 'new_post', true);
$category='review'; // category name for the post
$cat_ID = get_cat_ID( $category ); // need the id of 'review' category
//If it doesn't exist create new 'review' category
if($cat_ID == 0) {
$cat_name = array('review' => $category);
wp_insert_category($cat_name); // add new category
}
//Get ID of category again incase a new one has been created
$new_cat_ID = get_cat_ID($category);
$new_post = array(
'ID' => '',
'post_author' => $user->ID,
'tax_input' => array($category->taxonomy => array($category->review)),
'post_category' => array($new_cat_ID),
'post_content' => $post_content,
'post_title' => $post_title,
'post_value' => $value,
'post_type' => 'review',
'post_status' => 'pending'
);
$post_id = wp_insert_post($new_post);
$field_key_one = 'group_5fb2ace92f979';
$field_key_two = 'group_5fb2bcfd619dd';
$field_key_three = 'group_5fb2be0da827d';
$field_key_four = 'group_5fb2ace92f979';
$field_key_five = 'group_5fb2bf62167a1';
$value_one = $postStarOne;
$value_two = $postStarTwo;
$value_three = $postStarThree;
$value_four = $postStarFour;
$value_five = $postStarFive;
update_field($field_key_one, $value_one, $post_id);
update_field($field_key_two, $value_two, $post_id);
update_field($field_key_three, $value_three, $post_id);
update_field($field_key_four, $value_four, $post_id);
update_field($field_key_five, $value_five, $post_id);
// This will redirect you to the newly created post
//$post = get_post($post_id);
wp_redirect($post_id->guid);
}
?>
This is the code that I am using to bring in the data from the user. The update field is what I thought was supposed to bring in the data from the post into the custom field but I must be using it the wrong way. I'm not worried about the validation yet. When I get it up and running then I can validate. Any help will be appreciated. Thanks in advance
I have a plugin to create posts with data from an API. I have to check the state of the data on the api every time, if there is a change, it will update the posts and acf fields. I have a post title check so as not to duplicate posts. But how can I check posts correctly so that I can update acf fields every time if there is new data and not duplicate posts?
if( isset( $_POST['enable'] ) ) {
// JOB API
$url='https://api.com/test/';
$result = file_get_contents( $url );
$result_data = json_decode( $result );
foreach ($result_data as $job) {
$ref_code = $job->RefCode;
$post_title = $job->JobTitle;
$post_exists = post_exists( $post_title );
$job_id = $job->JobId;
$job_date = date('Y-m-d h:i:s', strtotime($job->Published));
if (!get_page_by_title($post_title, 'OBJECT', 'jobs') ) {
$data = array(
'post_type' => 'jobs',
'post_title' => $post_title,
'post_status' => 'publish',
'post_date' => $job_date,
'post_date_gmt' => $job_date
);
$post_id = wp_insert_post( $data );
wp_set_object_terms( $post_id, 'regulare-job', 'jobscat', 'post_tag' );
// Job DATA API
$job_api_url ='https://api.com/test/' . $ref_code;
$job_api_result = file_get_contents( $job_api_url );
$result_data = json_decode( $job_api_result );
//Update ACF fields
update_field( 'location', $job->RegionCity, $post_id );
update_field( 'job_intro', $result_data->Intro, $post_id );
update_field( 'job_offer', $result_data->data[0]->Text, $post_id );
update_field( 'job_requirement', $result_data->data[1]->Text, $post_id );
update_field( 'text_c2', $result_data->data[2]->Text, $post_id );
update_field( 'single_job_ref_code', $result_data->RefCode, $post_id );
}
}
}
I customized your code with some parts how i achieved it for myself.
It might need some customization. (See comments within code for additional info)
What I do:
1.) check if post is already existing based on your title (and get its id)
2.) if it is already existing => update data (ACF-Fields)
3.) if it is not existing => create new post and update meta data (ACF-Fields)
To fill the acf-fields I use a custom function based on ACF-Field-Keys.
You can also create a custom cron job to run this function every (minute, hour...)
function api_fetcher_function(){
if( isset( $_POST['enable'] ) ) {
// JOB API
$url='https://api.com/test/';
$result = file_get_contents( $url );
$result_data = json_decode( $result );
foreach ($result_data as $job) {
$ref_code = $job->RefCode;
$post_title = sanitize_title($job->JobTitle);
/* check if CPT-Post with given slug already exists */
$existing_post = get_page_by_path($post_title,'OBJECT', 'jobs');
$job_id = $job->JobId;
$job_date = date('Y-m-d h:i:s', strtotime($job->Published));
/* if post doesnt exist create a new one */
if($existing_post === null){
$inserted_post = wp_insert_post([
'post_name' => $post_title,
'post_title' => $post_title,
'post_type' => 'jobs',
'post_status' => 'publish',
'post_date' => $job_date,
'post_date_gmt' => $job_date
]);
/* continue after successful insert (single item) */
/* special error handling can be placed within if */
if( is_wp_error($inserted_post)){
continue;
}
/* Update Meta Info of new post */
updateJobsMeta($job, $inserted_post);
}else{
$existing_job_id = $existing_post->ID;
/*you can add some additional check if you have some timestamps within your api and ACF */
/*$existing_jobs_timestamp might not be needed => based on your available data*/
$existing_jobs_timestamp = get_field('updated_at', $existing_job_id);
/*if you have some timestamps to use*/
if($job->Published >= $existing_jobs_timestamp){
updateJobsMeta($job ,$existing_job_id);
}
/*if you dont have some timestamps to use just remove the if around the update function and the $existing_jobs_timestamp*/
}
}
}
}
function updateJobsMeta($job ,$id){
$ref_code = $job->RefCode;
$job_api_url ='https://api.com/test/' . $ref_code;
$job_api_result = file_get_contents( $job_api_url );
$result_data = json_decode( $job_api_result );
/* Update Fillable list based on your needs => keys can be found within your acf group in wp-backend (might be hidden by default) */
$fillable = [
'field_5f312082435dd' => $job->JobId,
'field_5f312095435de' => $job->JobTitle,
'acf_field_key....' => $job->Published
...
];
/* updates fields based on acf-key */
foreach($fillable as $key => $name){
update_field( $key, $name, $id);
}
}
I can successfully create a post and also update or insert the data to the custom fields.
But i've no Idea how to update or check the multiselect checkboxes.
Below is the code for creating a post with featured image and inserting custom fields.
Please suggest me to add also the multiple select checboxes.
<?php
error_reporting(E_ALL);
#ini_set('display_errors', 1);
require('wp-load.php');
global $user_ID;
$title = $_REQUEST['title'];
$content = $_REQUEST['content'];
$status = $_REQUEST['status'];
$date = $_REQUEST['date'];
$type = $_REQUEST['type'];
$bedrooms = $_REQUEST['bedrooms'];
$bathrooms = $_REQUEST['bathrooms'];
$floor = $_REQUEST['floor'];
$sqft = $_REQUEST['sqft'];
$afterfee = $_REQUEST['afterfee'];
$sp = $_REQUEST['saleprice'];
echo $title;
echo $content;
echo $status;
echo $type;
echo $bedrooms;
echo $bathrooms;
$new_post = array(
'post_title' => $title,
'post_content' => $content,
'post_status' => $status,
'post_date' => $date,
'post_author' => $user_ID,
'post_type' => $type,
'post_category' => array(0)
);
$id = wp_insert_post($new_post);
update_post_meta($id,'fave_property_bedrooms',$bedrooms);
update_post_meta($id,'fave_property_bathrooms',$bathrooms);
update_post_meta($id,'fave_video_url','www.google.com');
update_post_meta($id,'fave_property_price_postfix',$afterfee);
update_post_meta($id,'fave_property_land_postfix',$sqft);
update_post_meta($id,'fave_property_land',$floor);
update_post_meta($id,'fave_property_price_prefix','Start From');
update_post_meta($id,'fave_property_price_postfix','Per Month');
update_post_meta($id,'fave_property_price',$sp);
$post_id=$id;
// only need these if performing outside of admin environment
require_once(ABSPATH . 'wp-admin/includes/media.php');
require_once(ABSPATH . 'wp-admin/includes/file.php');
require_once(ABSPATH . 'wp-admin/includes/image.php');
// example image
$image = 'https://clevertechie.com/img/main/php-curl-tutorial.png';
// magic sideload image returns an HTML image, not an ID
$media = media_sideload_image($image, $post_id);
// therefore we must find it so we can set it as featured ID
if(!empty($media) && !is_wp_error($media)){
$args = array(
'post_type' => 'attachment',
'posts_per_page' => -1,
'post_status' => 'any',
'post_parent' => $post_id
);
// reference new image to set as featured
$attachments = get_posts($args);
if(isset($attachments) && is_array($attachments)){
foreach($attachments as $attachment){
// grab source of full size images (so no 300x150 nonsense in path)
$image = wp_get_attachment_image_src($attachment->ID, 'full');
// determine if in the $media image we created, the string of the URL exists
if(strpos($media, $image[0]) !== false){
// if so, we found our image. set it as thumbnail
set_post_thumbnail($post_id, $attachment->ID);
// only want one image
break;
}
}
}
}
?>
I have a series of custom tables which hold distillery operations data on the same MySQL DB as my Wordpress. I would like to use WPDB->GetResults and then WP_INSERT_POST to take form data and create a custom post type from certain distillery table entries. I have an HTML form trying to send a request to a PHP file (code below). I notice that I cannot even see the PHP when opening the webpage. There must be something wrong with this. When debugging the form submission, I am good up until my $.ajax({ call, but I think the .php file is getting me down.
-Newbie doing his best
<!DOCTYPE html>
<html>
<body>
<p>Goofball</p>
<?php
require('header.php');
require('mydomain/test/wp-includes/wp-db.php')
if(isset($_POST['mashId'])){
$mashId = $_REQUEST['mashId'];
new_mash_post($mashId);
}
function new_mash_post($mashId) {
// Initialize the page ID to -1. This indicates no action has been taken.
$post_id = -1;
$mashes = $wpdb->get_results(
"
SELECT *
FROM mash a
INNER JOIN mashbill b ON a.mashId = b.mashId
INNER JOIN mash_ferm_junc c ON a.mashId = c.mashId
WHERE a.mashId = $mashId
"
);
$oldmashid = 0;
foreach($mashes as $mash){
if($oldmashid != 0){
$oldmashid = $mash->mashId;
$slug = $mash->mashId;
$title = $mash->mashId;
$author_id = 1;
// If the page doesn't already exist, then create it
if( null == get_page_by_title( $title ) ) {
// Set the post ID so that we know the post was created successfully
$post_id = wp_insert_post(
array(
'comment_status' => 'closed',
'ping_status' => 'closed',
'post_author' => $author_id,
'post_name' => $slug,
'post_title' => $title,
'post_status' => 'publish',
'post_type' => 'your_bottle'
)
);
$json_result = array( 'success' => true, 'post_id' => $post_id);
echo json_encode( $json_result );
// Otherwise, we'll stop
} else {
// Arbitrarily use -2 to indicate that the page with the title already exists
$post_id = -2;
echo json_encode("failed");
} // end if
} //end if mashId is new
} //end for loop over selection results
} // end programmatically_create_post
?>
</body>
</html>
My aim is to insert a new draft post into the database via a custom front-end form I've created. I need the post title and content to be empty. Is this possible?
I've tried the following which doesn't work:
$post_data = array(
'post_title' => '',
'post_type' => 'post',
'post_content' => '',
'post_status' => 'draft',
'post_author' => 1
);
$post_id = wp_insert_post( $post_data );
Note: You can create a new post using the back-end editor with empty title and content so I am wondering how they guys at WordPress do it.
You can not insert a blank post with wp_insert_post, Wordpress will prevent it with wp_insert_post_empty_content hook, you can see it in the source code : https://developer.wordpress.org/reference/functions/wp_insert_post/
The only way to do it is to overpass this hook with a custom function
Here is an example (source)
add_filter('pre_post_title', 'wpse28021_mask_empty');
add_filter('pre_post_content', 'wpse28021_mask_empty');
function wpse28021_mask_empty($value)
{
if ( empty($value) ) {
return ' ';
}
return $value;
}
add_filter('wp_insert_post_data', 'wpse28021_unmask_empty');
function wpse28021_unmask_empty($data)
{
if ( ' ' == $data['post_title'] ) {
$data['post_title'] = '';
}
if ( ' ' == $data['post_content'] ) {
$data['post_content'] = '';
}
return $data;
}
There is a filter in WordPress core that can be used to prevent this.
wp_insert_post_empty_content
https://developer.wordpress.org/reference/hooks/wp_insert_post_empty_content/
Which you should be able to use like:
add_filter( 'wp_insert_post_empty_content', '__return_false' );
$post = wp_insert_post( $post_args );