I am calculating custom title for a product using WooCommerce add product page. After the user post product's information, title is generated and saved by a save_post filter hook.
add_filter('save_post', 'modify_post_title', '99', 1);
function modify_post_title($post_id)
{
// some logic to form a new $title
// ...
if (!empty($title)) {
// update the title in database
$wpdb->update($wpdb->posts, array('post_title' => $title), array('ID' => $post_id));
// UPDATE PERMALINK
}
}
I need to know what function to use to re-generate the permalink after updating title.
Thanks in advance
add_filter( 'wp_insert_post_data', 'custom_slug_change', 50, 2 );
function custom_slug_change( $data, $postarr ) {
//Check for the post statuses you want to avoid
if ( !in_array( $data['post_status'], array( 'draft', 'pending', 'auto-draft' ) ) ) {
$data['post_name'] = sanitize_title( $data['post_title'] );
}
return $data;
}
Would you please add above code in your functions.php ?
I think you can go with the window.history.pushState to maipulate the Browser History.
I think these may help you.
window.history.pushState("object or string", "Title", surl[0]);
Related
In the past, I've added custom fields to my products in WooCommerce. This was only visible at the back and not directly visible on the front end.
Now I can't get it done in any way. When I work with plugins, this only works on the product page as a selection. But I would like to configure it on the product page in the back for example after the regular price field (see example).
I'm looking for the right hooks to do this. Anyone have an idea where I can find this?
add_action('woocommerce_product_options_pricing', 'add_custom_fields_to_poduct_general');
function add_custom_fields_to_poduct_general() {
global $woocommerce, $post;
woocommerce_wp_text_input(
array(
'id' => '_custom_text',
'value' => get_post_meta($post->ID, '_custom_text', true),
'label' => __('Custom text', 'woocommerce'),
)
);
}
Add more fields after price using the hook woocommerce_product_options_pricing
add_action('woocommerce_process_product_meta', 'save_custom_product_field');
function save_custom_product_field($post_id) {
$key = '_custom_text';
$value = (!empty($_POST[$key]) ? wc_clean(wp_unslash($_POST[$key])) : '' ); // phpcs:ignore WordPress.Security.NonceVerification
if ($value) {
update_post_meta($post_id, $key, $value);
} else {
delete_post_meta($post_id, $key);
}
}
The hook woocommerce_process_product_meta is used to save the data added using the above hook
I use the code below to force WordPress to generate post slug from post title even when a user define a different slug or duplicate another slug but i want this to only affect a specific post type called job_listing but unfortunately it affects all post type on my site.
function myplugin_update_slug( $data, $postarr ) {
if ( ! in_array( $data['post_status'], array( 'draft', 'pending', 'auto-draft' ) ) ) {
$data['post_name'] = sanitize_title( $data['post_title'] );
}
return $data;
}
add_filter( 'wp_insert_post_data', 'myplugin_update_slug', 99, 2 );
How do i target only a specific post type called job_listing with the above code without affecting other post types
Can somebody help me amend this code to suit my need?
Your help will be appreciated.
According to the docs $data contains post_type so you should be able to use this:
function myplugin_update_slug( $data, $postarr ) {
if ( $data['post_type'] === 'job_listing' && ! in_array( $data['post_status'], array( 'draft', 'pending', 'auto-draft' ) ) ) {
$data['post_name'] = sanitize_title( $data['post_title'] );
}
return $data;
}
add_filter( 'wp_insert_post_data', 'myplugin_update_slug', 99, 2 );
I develop my first plugin, which creates some pages programatically by this method:
$page_id = wp_insert_post(
array(
'comment_status' => 'close',
'ping_status' => 'close',
'post_author' => 1,
'post_title' => 'HSN Form',
'post_name' => strtolower(str_replace(' ', '-', trim('hsn-form'))),
'post_status' => 'publish',
'post_type' => 'page',
)
);
And I set template file for it:
add_filter( 'page_template', 'hsn_service_form_page_template', 10, 1 );
function hsn_service_form_page_template( $page_template ){
if ( is_page( 'hsn-form' ) ) {
$page_template = plugin_dir_path(__DIR__) . 'service-form/form-template.php';
}
return $page_template;
}
After I would like to hide it completely from wordpress dashboard, but those have to available following way:
wwww.example.com/hsn-form.
I can hide it following code from Pages menu:
add_filter( 'parse_query', 'ts_hide_pages_in_wp_admin' );
function ts_hide_pages_in_wp_admin($query) {
global $pagenow,$post_type;
$page = get_page_by_path('hsn-form');
if (is_admin() && $pagenow=='edit.php' && $post_type =='page') {
$query->query_vars['post__not_in'] = array($page->ID);
}
}
It's ok, but it's still available in Appereance->Menu, where you can create nav menus.
I searched for it, but I can't find complete solution for my problem:
My plugin has to create some pages which are available this way: www.example.com/hsn-form
I need to hide this pages completely from admin dashboard
I would like to apply templates for these pages to add some custom php code.
So If somebody should know a complete solution for it, that should be great.
Thank you in advance!
change parse_query to pre_get_posts
In order to remove a page from the admin nav menu, you can hook into the admin_menu action, then manipulate the global $submenu variable.
add_action('admin_menu', function(){
global $submenu;
array_walk($submenu, function(&$child, $parent){
if( $parent != 'edit.php' )
return;
foreach($child as $key=>$submenu){
if( $submenu[2] == 'post-new.php' ) {
unset($child[$key]);
break;
}
}
});
});
In that example, we are looking for a subpage with the slug of post-new.php
underneath the top level page with the slug edit.php. If found, it gets altogether removed from the navigation menu.
The $submenu[2] part is looking for the slug element in the array. If you want to match by the submenu name instead, you can replace it with $submenu[0].
I try to add my products with as little human input as possible.
Therefor I'm looking for a solution to grab the title tag which is in my added product image and put it in the Product name field on or before saving the product. Any attempts to achieve this are failing because WordPress "thinks" that no title is given (so no slug could be generated). At least I think that this is the case.
See screenshot of the field
I tried to use a code snippet I found here on SO and to rework it to a working solution but I fail to get it right.
Here is the code I came up with:
function fcsp_set_title_on_save( $post_id ) {
$post_thumbnail_id = get_post_thumbnail_id( $post_id );
$filemeta = wp_get_attachment_metadata( $post_thumbnail_id, FALSE );
// Set this variable to false initially.
static $updated = false;
// If title has already been set once, bail.
if ( $updated ) {
return;
}
// Since we're updating this post's title, set this
// variable to true to ensure it doesn't happen again.
$updated = true;
$title = $filemeta['image_meta']['title'];
// Update the post's title.
wp_update_post( [
'ID' => $post_id,
'post_title' => $title,
] );
}
add_action( 'save_post', 'fcsp_set_title_on_save' );
Any idea how to accomplish this?
Please put this code in function.php if this is woocommerce you are using (I think rather than custom post type )
if(class_exists('WC_Admin_Meta_Boxes')) {
class wcsave extends WC_Admin_Meta_Boxes {
public function __construct() {
add_action( 'save_post', array( $this, 'save_meta_boxes' ), 1, 2 );
add_action( 'woocommerce_process_product_meta', 'WC_Meta_Box_Product_Data::save', 10, 2 );
}
public function save_meta_boxes( $post_id, $post ) {
//$_POST enter your post data here, this will help to control the post request from product woocommerce
//if product is updating don't execute image title code section
if(!empty($post->post_title)) {
return;
}
//if new product is being added.
if(!empty($_POST['post_ID']) && $post_id == $_POST['post_ID']) {
$post_thumbnail_id = get_post_thumbnail_id( $post_id );
$attachment_data = get_post( $post_thumbnail_id,OBJECT );
$title = count($attachment_data) > 0 ? $attachment_data->post_title : "PRODUCT-".$post_id;
remove_action( 'save_post', array( $this, 'save_meta_boxes' ) , 1, 2 );
wp_update_post( [
'ID' => $post_id,
'post_title' => $title,
'post_status' => $post->post_status
] );
// re-hook this function
add_action( 'save_post', array( $this, 'save_meta_boxes' ) , 1, 2 );
}
}
}
new wcsave();
}
But please note, as I've tested you need at least some other info along with product image you are uploading like product description, rest it will save the image name as product title.
Thanks
I would like to process a contact form from contact form 7 into a custom post type.
Currently, this is what I have:
<?php
if ( 'POST' == $_SERVER['REQUEST_METHOD'] && !empty( $_POST['action'] ) && $_POST['action'] == "front_post") {
//store our post vars into variables for later use
//now would be a good time to run some basic error checking/validation
//to ensure that data for these values have been set
$title = $_POST['title'];
$content = $_POST['content'];
$Interest = $_POST['Interest'];
$post_type = 'purchase';
//the array of arguements to be inserted with wp_insert_post
$new_post = array(
'post_title' => $title,
'post_content' => $content,
'tags_input' => $tags,
'posted_data' => $Interest,
'post_status' => 'publish',
'post_category' => array('0',$_POST['cat']),
'post_type' => $post_type
);
//insert the the post into database by passing $new_post to wp_insert_post
//store our post ID in a variable $pid
//we now use $pid (post id) to help add out post meta data
$pid=wp_insert_post($new_post);
//we now use $pid (post id) to help add out post meta data
add_post_meta($pid, 'cust_key', $custom_field);
}
?>
Here is a link to the actual form: http://stage.icardpromotions.com/create-purchase-order/
I need to be able to pull in all of the info form this form into the custom post type "purchase"
As you can see, I am currently pulling in the post_content, post_title, etc.
I have also tried to pull in content from content form by input name "Interest" but it dose not work.
Does anyone have a clue how to do this?
function save_posted_data( $posted_data ) {
$args = array(
'post_type' => 'post',
'post_status'=>'draft',
'post_title'=>$posted_data['your-name'],
'post_content'=>$posted_data['your-message'],
);
$post_id = wp_insert_post($args);
if(!is_wp_error($post_id)){
if( isset($posted_data['your-name']) ){
update_post_meta($post_id, 'your-name', $posted_data['your-name']);
}
// if( isset($posted_data['your-email']) ){
// update_post_meta($post_id, 'your-email', $posted_data['your-email']);
// }
// if( isset($posted_data['your-subject']) ){
// update_post_meta($post_id, 'your-subject', $posted_data['your-subject']);
// }
if( isset($posted_data['your-message']) ){
update_post_meta($post_id, 'your-message', $posted_data['your-message']);
}
//and so on ...
return $posted_data;
}
}
add_filter( 'wpcf7_posted_data', 'save_posted_data' );
-------------------- Explaining It-------------------------
First make function and add a hook wpcf7_posted_data to it
---first step---
function save_posted_data( $posted_data ) {
}
add_filter( 'wpcf7_posted_data', 'save_posted_data' );
---second step---
and now u need to add some arguments to the post that needs to be populated using wp_insert_post();
$args = array(
'post_type' => 'post',
'post_status'=>'draft',
'post_title'=>$posted_data['your-name'],
'post_content'=>$posted_data['your-message'],
);
$post_id = wp_insert_post($args);
---third step---
check if that populated items is error or not
if(!is_wp_error($post_id)){ //do ur stuffs }
---fourth step---
now checking isset the field or not and updating the metas
eg post
if( isset($posted_data['your-name']) ){
update_post_meta($post_id, 'your-name', $posted_data['your-name']);
}
and in last return the value
return $posted_data;
Full code is above.
here is a quick tip as to how to go about achieving the above using your own code, first register your custom post
add_action('init', 'my_custom_post');
function (){
$args = array(
/*post type registration parameters*/
);
register_post_type( 'my_custom_post', $args );
}
next, you want to capture your posted data and create a new post
add_filter( 'wpcf7_posted_data', 'save_posted_data' );
function save_posted_data( $posted_data ) {
$args = array(
'post_type' => 'my_custom_post',
/*other default parameters you want to set*/
);
$post_id = wp_insert_post($args);
if(!is_wp_error($post_id)){
if( isset($posted_data['form-field-name']) ){
update_post_meta($post_id, 'form-field-name', $posted_data['form-field-name']);
}
//and so on ...
return $posted_data;
}
While the answer with the most upvotes in this thread works it has some flaws.
First of which is: you can still submit the form and thus create a post in wordpress if for instance you remove "disabled" tag from your submit button. So you can essentially bypass the validation.
Second problem that I had, was probably specific to my usecase, since this function triggers on any cf7 form submission on website. If you have more than one cf7 form this will create posts even if users submit something in some totally different form.
To solve the first problem I think the best way is to hook custom function to "wpcf7_before_send_mail" instead of "wpcf7_posted_data"
And to solve the second problem is to check for id of the form you wish to trigger the effect on.
This is how I solved these problems:
function save_cf7_data_to_cpt( $contact_form ) {
if( $contact_form->id() !== $my_form_id )
return; //dont run the rest if it is not the form you want it to be, $my_form_id we look up in admin or shortcode...
$submission = WPCF7_Submission::get_instance();
if ( $submission ) {
$posted_data = $submission->get_posted_data();
} //we get to $post_data in this way since it is not provided like in the wpcf7_posted_data approach
$args = array(
'post_type' => 'testemonial',
'post_status'=>'draft',
'post_title'=>$posted_data['your-name'],
'post_content'=>$posted_data['your-message'],
);
$post_id = wp_insert_post($args);
if(!is_wp_error($post_id)){
if( isset($posted_data['your-name']) ){
update_post_meta($post_id, 'your-name', $posted_data['your-name']);
}
if( isset($posted_data['your-message']) ){
update_post_meta($post_id, 'your-message', $posted_data['your-message']);
}
//and so on ...
return $posted_data;
}
}
add_filter( 'wpcf7_before_send_mail', 'save_cf7_data_to_cpt' ); //hook into wpcf7_before_send_mail to ensure validation is ok
Can u also use
add_action('wpcf7_mail_sent','save_my_form_data_to_my_cpt');
add_action('wpcf7_mail_failed','save_my_form_data_to_my_cpt');
function save_my_form_data_to_my_cpt($contact_form){
$submission = WPCF7_Submission::get_instance();
if (!$submission){
return;
}
$posted_data = $submission->get_posted_data();
//The Sent Fields are now in an array
//Let's say you got 4 Fields in your Contact Form
//my-email, my-name, my-subject and my-message
//you can now access them with $posted_data['my-email']
//Do whatever you want like:
$new_post = array();
if(isset($posted_data['your-name']) && !empty($posted_data['your-name'])){
$new_post['post_title'] = $posted_data['your-name'];
} else {
$new_post['post_title'] = 'Message';
}
$new_post['post_type'] = 'inquiry'; //insert here your CPT
if(isset($posted_data['tel-901'])){
$new_post['post_content'] = $posted_data['tel-901'];
} else {
$new_post['post_content'] = 'No Message was submitted';
}
$new_post['post_status'] = 'publish';
//you can also build your post_content from all of the fields of the form, or you can save them into some meta fields
if(isset($posted_data['your-email']) && !empty($posted_data['your-email'])){
$new_post['meta_input']['sender_email_address'] = $posted_data['your-email'];
}
if(isset($posted_data['checkbox-674']) && !empty($posted_data['checkbox-674'])){
//$new_post['meta_input']['sender_name'] = $posted_data['checkbox-674'];
$ChildSeat=$posted_data['checkbox-674'];
$Child_Seat='';
for($a=0;$a<count($ChildSeat);$a++)
{
$data['checkbox-674']=$_POST['checkbox-674'][$a];
$Child_Seat.=$data['checkbox-674'].'<br>';
$new_post['post_content'] = $Child_Seat;
}
}
//When everything is prepared, insert the post into your Wordpress Database
if($post_id = wp_insert_post($new_post)){
//Everything worked, you can stop here or do whatever
} else {
//The post was not inserted correctly, do something (or don't ;) )
}
return;
}
there is a plugin to do this, Post My CF7 Form.
The plugin allows you to map a CF7 form and its fields to a an existing post type or a new custom post type.
The mapping process is done using an interactive UI admin page which gives you the option to map your fields to post fields (title, content, excerpt, slug, author) as well as post meta-fields.
In addition, the plugin also introduces a save submit button to allow users to save a draft version of the form, this is especially useful for large complex forms.
The plugin can automatically load taxonomy terms in select/checkbox/radio fields that have been mapped to that taxonomy, thus enabling created posts to be automatically assigned to users selected terms.
The plugin has multiple hooks & filters to customise the process flow.