WordPress Conditional Post Creation - wordpress

I want this plugin to only create the post with title "Test Post" if it doesn't already exist. For some reason it always creates the post when I activate the plugin. Seems get_page_by_title('Test Post') is always false even after the post has been created. Can someone please explain why?
<?php
/* Plugin Name: Create Test Post */
function create_post(){
if(get_page_by_title('Test Post')){
return;
}
$my_post = array(
'post_title' => 'Test Post',
'post_content' => 'This is a test post',
'post_status' => 'publish'
);
wp_insert_post($my_post);
} // end create_post
register_activation_hook(__FILE__, create_post);

The function get_page_by_title() can only be used on pages, not posts without setting the post type argument.
This will set the appropriate argument for that function. If 'post' is not working try using 'posts'.
The full documentation for this function is found here.
https://developer.wordpress.org/reference/functions/get_page_by_title/
function create_post(){
$prev_post = get_page_by_title('Test Post', 'OBJECT', 'post');
if ($prev_post != NULL) {
$prev_post_status = get_post_status( $prev_post->ID );
}
if (!isset($prev_post_status) || !in_array($prev_post_status, array('trash', 'published')) ) {
$my_post = array(
'post_title' => 'Test Post',
'post_content' => 'This is a test post',
'post_status' => 'publish'
);
wp_insert_post($my_post);
}
} // end create_post
register_activation_hook(__FILE__, create_post);

Related

How do I add a new page using code thru a Wordpress plugin?

I followed the chosen answer here -> How to create new page in wordpress plugin?
and I added the following code in a new Wordpress plugin folder and file and then activated in the Wordpress admin menu. Yet I don't have a new page created when I go to the slug demosite.com/custom/
add_action( 'admin_menu', 'register_newpage' );
function register_newpage(){
add_menu_page('custom_page', 'custom', 'administrator','custom', 'custompage');
remove_menu_page('custom');
}
Do I have to do something special to make my Wordpress plugin code work? I really need to be able to add a new page using my plugin functionality.
For create fronted page when plugin activation used register_activation_hook() like below.
register_activation_hook() function registers a plugin function to be run when the plugin is activated.
The first thing we do on activation is check that the current user is allowed to activate plugins. We do this using the current_user_can function
Finally, we create our new page, after we check that a page with the same name does not exist
register_activation_hook( __FILE__, 'register_newpage_plugin_activation' );
function register_newpage_plugin_activation() {
if ( ! current_user_can( 'activate_plugins' ) ) return;
global $wpdb;
if ( null === $wpdb->get_row( "SELECT post_name FROM {$wpdb->prefix}posts WHERE post_name = 'new-page-slug'", 'ARRAY_A' ) ) {
$current_user = wp_get_current_user();
// create post object
$page = array(
'post_title' => __( 'New Page' ),
'post_status' => 'publish',
'post_author' => $current_user->ID,
'post_type' => 'page',
);
// insert the post into the database
wp_insert_post( $page );
}
}
Here is a full list of parameters accepted by the wp_insert_post function
After plugin active successfully you can access your page using demosite.com/new-page-slug/
I'm not sure if you intended for the page to be created only once if so you should do it during plugin activation.
You might want to consider the following pseudo-ish code:
register_activation_hook( __FILE__, 'moveFile' );
function moveFile(){
if( check if post exists ){
wp_insert_post() # obviously title is "whatever", following convention
#move the file to themes folder
$source = plugin_dir_path(__FILE__) . "page-whatever.php";
$destination = get_template_directory() . "/page-whatever.php";
$cmd = 'cp ' . $source . ' ' . $destination;
exec($cmd);
}
}
It's similar to the code answered by Ankur, but this sample let you have a custom page. Caveat, my method uses exec() command.
I hope this helps.
/* If you want create a page with syn page template on plugin activation so see below example */
register_activation_hook( __FILE__, 'activate' );
function activate() {
$the_slug = 'our-services';
$args = array(
'name' => $the_slug,
'post_type' => 'post',
'post_status' => 'publish',
'numberposts' => 1
);
$my_posts = get_posts($args);
if(empty($my_posts)){
$my_post = array(
'post_title' => 'Our Services',
'post_content' => '',
'post_status' => 'publish',
'post_author' => 1,
'post_type' => 'page',
'post_name' => 'our-services'
);
// Insert the post into the database
$post_id=wp_insert_post( $my_post );
update_post_meta( $post_id, '_wp_page_template', 'page-templates/our-services.php' );
}
}
/* page-template - our-services.php* /
<?php
/*
* Template Name: our-services
*/
get_header();
get_footer();
?>

Why wp_update_post return invalid post id

I am getting an error with WordPress wp_update_post() function that says "Invalid post ID". Here is my code:
$current_item = 273;
$my_post = array(
'ID' => $current_item,
'post_title' => 'This is the post title.',
'post_content' => 'This is the updated content.',
);
$post_id = wp_update_post( $my_post, true );
if (is_wp_error($post_id)) {
$errors = $post_id->get_error_messages();
foreach ($errors as $error) {
echo $error;
}
}
Thanks in advance .
Use 'import_id', not 'ID'.
If there is no post at the ID you specify, wp_update_post() doesn't create a new one - it returns an error. In order to specify the ID of a new post use 'import_id' => $current_item.
Note, though, that if there IS a post with that ID, import_id will cause a new post instead of an update. So if you want to EITHER make a new post with that ID OR update the post at that ID, you'll need an if statement to pick your key:
$newPostKey = (get_post_status($current_item)) ? 'ID' : 'import_id';
// If there's a post with an ID of $current_item, we'll use 'ID'.
// Otherwise, use 'import_id'.
Here's your shiny new code.
$current_item = 273;
$newPostKey = (get_post_status($current_item)) ? 'ID' : 'import_id';
$my_post = array(
$newPostKey => $current_item,
'post_title' => 'This is the post title.',
'post_content' => 'This is the updated content.',
);
$post_id = wp_update_post( $my_post, true );

Creating a page with wp_insert_post()

I have a form that collects data about a user's product and then creates a page in WordPress with
$my_post = array(
'post_content' => "My page content",
'post_title' => $product_title,
'post_name' => $product_title,
'post_type' => 'page', // must be 'page' to accept the 'page_template' below
'page_template' => "listing.php",
'post_status' => "publish"
);
$ID = wp_insert_post( $my_post );
$permalink = get_permalink($ID);
echo "<br />ID for new page is $ID, Permalink for new page is $permalink";
The form data is put into meta variables for the page ID and the listing.php template file pulls it out of there and builds the HTML to display the product page. This all works fine and I can see that the page meta variable, _wp_page_template, gets set correctly to the template file I specified, listing.php:
Now I want to create a second page from the same form data, this one displaying different parts of the data in a different way. So I've added a second block of code, starting at $my_cert below, that creates this second page and specifies a different template, certificate.php, that knows how to build the second version of the data.
$my_post = array(
'post_content' => "My page content",
'post_title' => $product_title,
'post_name' => $product_title,
'post_type' => 'page', // must be 'page' to accept the 'page_template' below
'page_template' => "listing.php",
'post_status' => "publish"
);
$ID = wp_insert_post( $my_post );
$permalink = get_permalink($ID);
echo "<br />ID for new page is $ID, Permalink for new page is $permalink";
$my_cert = array(
'post_content' => "My certificate", // post_content is required
'post_title' => "My certificate", // post_title is required
'post_name' => "My certificate",
'post_type' => 'page', // must be 'page' to accept the 'page_template' below
'page_template' => "certificate.php",
'post_status' => "publish"
);
$CERT_ID = wp_insert_post( $my_cert );
$cert_permalink = get_permalink($CERT_ID);
echo "<br />ID for new certificate is $CERT_ID, Permalink for new certificate is $cert_permalink";
But when I look in the meta data for the second page created, the template is set to "default" instead of certificate.php:
I know I've set up certificate.php correctly as a template (set /* Template Name: certificate */ at the top) because the Page Edit Template dropdown includes certificate:
So does anyone see why I can't create this second page with the template set to certificate.php?
Thanks
Are you sure your page template src for: certificate.php is: certificate.php? And not: templates/certificate.php or something like that. Look in your theme folder and be 100% of the page template path. Check your spelling or for typos in the page template path or name. It must be an exact match.
If you still have problems I would look into and debug the source code of: wp_insert_post()
if ( ! empty( $postarr['page_template'] ) && 'page' == $data['post_type'] ) {
$post->page_template = $postarr['page_template'];
$page_templates = wp_get_theme()->get_page_templates( $post );
if ( 'default' != $postarr['page_template'] && ! isset( $page_templates[ $postarr['page_template'] ] ) ) {
if ( $wp_error ) {
return new WP_Error('invalid_page_template', __('The page template is invalid.'));
}
update_post_meta( $post_ID, '_wp_page_template', 'default' );
} else {
update_post_meta( $post_ID, '_wp_page_template', $postarr['page_template'] );
}
}
So its probably this part that fails:
if ( 'default' != $postarr['page_template'] && ! isset( $page_templates[ $postarr['page_template'] ] ) )
Try to modify: wp-includes/post.php and go to the definition of: function wp_insert_post() on row: 2872. And add a new row on row: 3312 for debugging purposes.
echo '<pre>';
print_r( $page_templates );
echo '</pre>';
die();
Make sure your certificate.php is among those in that array. Remember to delete the debug code before continuing. This should give you some answers.

Wordpress: wp_insert_post() firing multiple times

I'm building a simple WP plugin that's supposed to create a new post and save some meta for the post. I created a function with the functionality and for the time being I hooked it to the 'init' event to check if it works.
add_action( 'init', 'my_func' );
function my_func() {
$my_post = array(
'post_title' => 'Some Post Title',
'post_name' => 'some-post-title',
'post_type' => 'custom-post-type',
'post_status' => 'publish'
);
$inserted_post_id = wp_insert_post($my_post);
if($inserted_post_id != 0) {
add_post_meta($inserted_post_id, 'some-key', 'some-value');
add_post_meta($inserted_post_id, 'some-other-key', 'some-other-value');
echo 'SUCCESS';
} else {
echo 'ERROR';
}
}
Now, whenever I reload the admin page, I get the 'SUCCESS' message echoed out, and I also get 4-6 new post called 'Some Post Title', and 4-6*2 new entries in the postmeta table. The 'SUCCESS' message echoes only once, meaning the function runs only once, still I get the data inserted to the database multiple times. What am I doing wrong?
Check before going to insert new post if already exists or not. So get_page_by_title('Some Post Title') == false then only insert new post.
add_action( 'init', 'my_func' );
function my_func() {
$my_post = '';
if( get_page_by_title('Some Post Title','OBJECT','custom-post-type') == NULL )
$my_post= array(
'post_title' => 'Some Post Title',
'post_name' => 'some-post-title',
'post_type' => 'custom-post-type',
'post_status' => 'publish'
);
wp_insert_post( $my_post );
}

Update wordpress post from front-end (using acf)

I am making front end admin for users to add/edit their posts. I already made post add form and it works, but edit form doesnt work.
functions.php
function add_new_post( $post_id )
{
if( $post_id == 'new' ) {
// Create a new post
$post = array(
'post_title' => $_POST["fields"]['field_52c810cb44c7a'],
'post_category' => array(4),
'post_status' => 'draft',
'post_type' => 'post'
);
// insert the post
$post_id = wp_insert_post( $post );
return $post_id;
}
else {
return $post_id;
}
}add_filter('acf/pre_save_post' , 'add_new_post' );
index.php
<div id="updateform-<?php the_ID(); ?>" class="collapse">
<?php
echo get_the_ID();
$args = array(
'post_id' => get_the_ID(), // post id to get field groups from and save data to
'field_groups' => array(31), // this will find the field groups for this post (post ID's of the acf post objects)
'form' => true, // set this to false to prevent the <form> tag from being created
'form_attributes' => array( // attributes will be added to the form element
'id' => 'post',
'class' => '',
'action' => get_permalink( get_the_ID() ),
'method' => 'post',
),
'return' => add_query_arg( 'updated', 'true', get_permalink() ), // return url
'html_before_fields' => '', // html inside form before fields
'html_after_fields' => '', // html inside form after fields
'submit_value' => 'Update', // value for submit field
'updated_message' => 'Post updated.', // default updated message. Can be false to show no message
);
acf_form( $args );
?>
</div>
For saving posts you should use save_post not pre_save_post.
Basically pre_save_post is used for new posts.
Use this below add_filter('save_post' , 'add_new_post');
I created plugins for that:
Forms actions
https://wordpress.org/plugins/forms-actions/
Add actions to yours ACF forms.
ACF Frontend display
https://wordpress.org/plugins/acf-frontend-display/
Display your ACF form on frontend
If by some chance you happen to be using Elementor Page Builder, you can do this by installing Advanced Widgets for Elementor. It comes with an ACF Form widget that you can just drag & drop anywhere into your site and configure your form through the UI (no coding required).

Resources