Custom post type url rewriting - wordpress

I am rewriting the url of CPT 'entertainment' to /entertainment/%year%/%monthnum%/%post_id%/ It is re-writing but gives 404 not found error. How can I solve this?
Here is my code:
add_action( 'init', 'my_rewrite');
function my_rewrite() {
global $wp_rewrite;
$entertainment_structure = '/entertainment/%year%/%monthnum%/%post_id%/';
$wp_rewrite->add_rewrite_tag("%entertainment%", '([^/]+)', "entertainment=");
$wp_rewrite->add_permastruct('entertainment', $entertainment_structure, false);
flush_rewrite_rules();
}
// Add filter to plugin init function
add_filter('post_type_link', 'entertainment_permalink', 10, 3);
// Adapted from get_permalink function in wp-includes/link-template.php
function entertainment_permalink($permalink, $post_id, $leavename) {
$post = get_post($post_id);
$rewritecode = array(
'%year%',
'%monthnum%',
'%day%',
'%hour%',
'%minute%',
'%second%',
$leavename? '' : '%post_id%',
'%post_id%',
'%category%',
'%author%',
$leavename? '' : '%post_id%',
);
if ( '' != $permalink && !in_array($post->post_status, array('draft', 'pending', 'auto-draft')) ) {
$unixtime = strtotime($post->post_date);
$category = '';
if ( strpos($permalink, '%category%') !== false ) {
$cats = get_the_category($post->ID);
if ( $cats ) {
usort($cats, '_usort_terms_by_ID'); // order by ID
$category = $cats[0]->slug;
if ( $parent = $cats[0]->parent )
$category = get_category_parents($parent, false, '/', true) . $category;
}
// show default category in permalinks, without
// having to assign it explicitly
if ( empty($category) ) {
$default_category = get_category( get_option( 'default_category' ) );
$category = is_wp_error( $default_category ) ? '' : $default_category->slug;
}
}
$author = '';
if ( strpos($permalink, '%author%') !== false ) {
$authordata = get_userdata($post->post_author);
$author = $authordata->user_nicename;
}
$date = explode(" ",date('Y m d H i s', $unixtime));
$rewritereplace =
array(
$date[0],
$date[1],
$date[2],
$date[3],
$date[4],
$date[5],
$post->ID,
$post->ID,
$category,
$author,
$post->ID,
);
$permalink = str_replace($rewritecode, $rewritereplace, $permalink);
} else { // if they're not using the fancy permalink option
}
return $permalink;
}
If I replace $entertainment_structure = '/entertainment/%year%/%monthnum%/%post_id%/'; with $entertainment_structure = '/entertainment/%year%/%monthnum%/%entertainment%/'; it works fine

You aren't supposed to hook init, but either register_activation_hook() it, if its a plugin or use after_switch_theme if its a theme (its important to either deactivate/reactivate the plugin or switch themes in order for your rewrites to apply). <= further read here
You might want to have a read of the rewrite API

Related

Can't add to cart (custom function) when not logged

this function was working fine but since few days (and few updates Wp 5.9 to 6.X And others plugins) it only work when i'm logged in!.. For normal Users. the form post but the Cart is empty.. This function is used to add in bulk one ore more variation of the same product..
The function is in my child theme and was working for 1 year.. unfortunately.. i can't find a backup from before my updates!?! SHAME ON ME!!
function cps_add_multiple_products_to_cart() {
if ( empty( $_REQUEST['add-to-cart-manual'] )) {
return;
}
global $woocommerce;
$active_step = active_step();
$step_urls = step_urls();
//'add-to-cart' should be in this format - product_id1|variation_id1|variation_attribute1|variation_value1,product_id2|variation_id2|variation_attribute2|variation_value2 ... this is the format - product_id1|variation_id1|variation_attribute1|variation_value1,product_id2|variation_id2|variation_attribute2|variation_value2
$product_var_ids = explode( ',', $_REQUEST['add-to-cart-manual'] ); //product with variation ids that needs to be added
foreach ( $product_var_ids as $product_var_id ) {
$pdt_var_temp = explode( '|', $product_var_id );
$product_id = $pdt_var_temp[0];
$variation_id = $pdt_var_temp[1];
$variation_attribute = $pdt_var_temp[2];
$variation_attribute_value = $pdt_var_temp[3];
$variation_qte = $pdt_var_temp[4];
$pdt_in_cart = false;
foreach ( $woocommerce->cart->cart_contents as $key => $values ) {
if( in_array( $values['variation_id'], $variation_id ) ) {
$pdt_in_cart = true;
}
}
if ( !$pdt_in_cart ) {
$quantity = $variation_qte;
if ($quantity > 0) {
$variation = array( $variation_attribute => $variation_attribute_value );
$woocommerce->cart->add_to_cart( $product_id, $quantity, $variation_id, $variation );
}
}
}
}
add_action( 'woocommerce_before_main_content', 'cps_add_multiple_products_to_cart', 15 );

Get Post ID of post you're currently editing in WordPress

I'm attempting to get the ID of the post I am editing in functions.php for the purpose of dynamically rewriting a custom post type slug.
This is what I'm working with so far.
function change_post_type_slug( $args, $post_type ) {
if ( 'custom_post' == $post_type ) {
global $post;
$location = get_field('custom_field', $post->ID);
$args['rewrite']['slug'] = $location;
}
return $args;
}
add_filter( 'register_post_type_args', 'change_post_type_slug', 10, 2 );
I am not sure if the hook register_post_type_args is firing before I am able to get the ID, or if this is even the best way to go about what I am trying to accomplish. Can't find much out there on the subject.
I was able to get it to work with the following:
function change_post_type_slug( $args, $post_type ) {
if ( 'lead_page' == $post_type ) {
$post_id = $_GET['post'];
$location = get_field('leadpage_location', $post_id);
$args['rewrite']['slug'] = $location->post_name;
}
return $args;
}
add_filter( 'register_post_type_args', 'change_post_type_slug', 10, 2 );
However it resulted in a notice on the front-end:
Notice: Undefined index: post in /path/to/wordpress/functions.php on line 623
Line 623 is $post_id = $_GET['post'];
You should use the updated_postmeta hook for this, as its run every time you update your custom fields.
Then you can update your post data with wp_update_post() function.
add_action( 'updated_postmeta', function( $meta_id, $object_id, $meta_key, $meta_value ) {
if ( 'location' === $meta_key ) {
wp_update_post([
'ID' => $object_id,
'post_name' => $meta_value,
]);
}
}, 10, 4 );
Update:
Try this:
function change_post_types_slug( $args, $post_type ) {
if ( 'your-custom_post' === $post_type ) {
// Check and get the custom post ID
$id = isset($_GET[ 'post' ]) ? $_GET[ 'post' ] : '' ;
// $location = get_field('leadpage_location', $id);
$args['rewrite']['slug'] = 'new-slug-here';
}
return $args;
}
add_filter( 'register_post_type_args', 'change_post_types_slug', 10, 2 );
Try this out:
function change_post_type_slug( $args, $post_type ) {
if ( 'lead_page' === $post_type && is_admin() && $_GET['action'] === 'edit' ) {
$post_id = $_GET['post'];
$location = get_field('leadpage_location', $post_id);
$args['rewrite']['slug'] = $location->post_name;
}
return $args;
}
add_filter( 'register_post_type_args', 'change_post_type_slug', 10, 2 );
It adds two more conditionals, to check if you're on the admin screen and to check of there is a GET parameter of edit. Probably overkill to do is_admin() as well, but now you're super safe.

Wordpress: remove one category in permaling /%category%/%postname%/

I am looking for a solution in order to remove /%category%/ from my permalinks for only one category ("general").
My permalink is currently set to /%category%/%postname%/. How can I create the following URLs only for the "general" category /%postname%/ ?
Thanks!
You can set custom structure in Permalinks Settings: Dashboard - Settings>Permalinks
This works for me:
function remove_uncategorized( $permalink, $post, $leavename ) {
if( $post->post_type != 'post' ) return $permalink;
$cats = get_the_category($post->ID);
if( ! count($cats) ) return $permalink;
usort($cats, '_usort_terms_by_ID');
$category_object = apply_filters( 'post_link_category', $cats[0], $cats, $post );
$category_object = get_term( $category_object, 'category' );
return _clear_uncategorized($category_object, $permalink);
}
function _clear_uncategorized($cat, $permalink) {
if( $cat->slug == 'sin-categoria' ) {
return str_replace('%category%/', '', $permalink);
}
$parent = $cat->parent;
if ( !$parent )
return $permalink;
return _clear_uncategorized($parent, $permalink);
}
add_filter( 'pre_post_link', 'remove_uncategorized', 9, 3 );

WordPress REST API - hide field for non logged users

With this example I manage to add custom post type and custom meta data in WordPress REST API.
Right now I'm trying to hide some of the data for non logged users and I'm trying like this:
add_filter( 'rest_prepare_the_event', 'add_meta_to_json', 10, 3 );
function add_meta_to_json($data, $post, $request){
$response_data = $data->get_data();
if ( $request['context'] !== 'view' || is_wp_error( $data ) ) {
return $data;
}
$start = get_post_meta( $post->ID, '_the_event_start', true );
if(empty($start)){
$start = '';
}
$end = get_post_meta( $post->ID, '_the_event_end', true );
if(empty($end)){
$end = '';
}
$location = get_post_meta( $post->ID, '_the_event_location', true );
if(empty($location)){
$location = '';
}
if($post->post_type == 'the_event'){
$response_data['event_meta'] = array(
'start' => $start,
'end' => $end,
'location' => $location,
);
if ( !is_user_logged_in() ) {
unset($response_data['event_meta']['location']);
}
}
$data->set_data( $response_data );
return $data;
}
In above example code I'm trying to hide location field to non logged users but this is not working.
How to hide that field for non logged users?
I see your code fine... but you can to try:
if($post->post_type == 'the_event'){
$response_data['event_meta'] = array(
'start' => $start,
'end' => $end
);
if ( is_user_logged_in() ) {
$response_data['event_meta']['location'] = $location;
}
}

How to make custom form-tag in contact form 7 required

So i make custom form-tag in contact form 7! It is a drop down with list of my courses and now I want to make it required because that is the main thing in whole form.
So can someone give me a tip how to do that?
When I do the [myCustomField* course-name class:custom-field]
It does not working with *
So if someone can help it will be great!
I have been working on this myself this afternoon and I do not think Mahmoud has added everything that is needed to get the validation working well and the messages showing up.
using what I have learnt from the posts on contact form 7 here:
https://contactform7.com/2015/01/10/adding-a-custom-form-tag
https://contactform7.com/2015/02/27/using-values-from-a-form-tag/
and looking at this file in the plugin: contact-form-7/modules/select.php which helped a lot.
I think this will work better and needs to be added to your functions.php file in your child-theme.
add_action( 'wpcf7_init', 'custom_add_form_tag_myCustomField' );
function custom_add_form_tag_myCustomField() {
wpcf7_add_form_tag( array( 'myCustomField', 'myCustomField*' ),
'custom_myCustomField_form_tag_handler', true );
}
function custom_myCustomField_form_tag_handler( $tag ) {
$tag = new WPCF7_FormTag( $tag );
if ( empty( $tag->name ) ) {
return '';
}
$validation_error = wpcf7_get_validation_error( $tag->name );
$class = wpcf7_form_controls_class( $tag->type );
if ( $validation_error ) {
$class .= ' wpcf7-not-valid';
}
$atts = array();
$atts['class'] = $tag->get_class_option( $class );
$atts['id'] = $tag->get_id_option();
if ( $tag->is_required() ) {
$atts['aria-required'] = 'true';
}
$atts['aria-invalid'] = $validation_error ? 'true' : 'false';
$atts['name'] = $tag->name;
$atts = wpcf7_format_atts( $atts );
$myCustomField = '';
$query = new WP_Query(array(
'post_type' => 'CUSTOM POST TYPE HERE',
'post_status' => 'publish',
'posts_per_page' => -1,
'orderby' => 'title',
'order' => 'ASC',
));
while ($query->have_posts()) {
$query->the_post();
$post_title = get_the_title();
$myCustomField .= sprintf( '<option value="%1$s">%1$s</option>',
esc_html( $post_title ) );
}
wp_reset_query();
$myCustomField = sprintf(
'<span class="wpcf7-form-control-wrap %1$s"><select %2$s>%3$s</select>%4$s</span>',
sanitize_html_class( $tag->name ),
$atts,
$myCustomField,
$validation_error
);
return $myCustomField;
}
That is how we create the custom tag. The important differences here are the addition of the $validation_error variables as wells the aria-required and aria-invalid data. It is also important to include the $validation_error in the final output so that we can see the validation messages being created.
Then to finish it off we need to add some validation via filters.
There is no documentation on this yet, but I used the functions from the select.php and altered them to what I needed.
/* Validation filter */
add_filter( 'wpcf7_validate_myCustomField', 'wpcf7_myCustomField_validation_filter', 10, 2 );
add_filter( 'wpcf7_validate_myCustomField*', 'wpcf7_myCustomField_validation_filter', 10, 2 );
function wpcf7_myCustomField_validation_filter( $result, $tag ) {
$tag = new WPCF7_FormTag( $tag );
$name = $tag->name;
if ( isset( $_POST[$name] ) && is_array( $_POST[$name] ) ) {
foreach ( $_POST[$name] as $key => $value ) {
if ( '' === $value ) {
unset( $_POST[$name][$key] );
}
}
}
$empty = ! isset( $_POST[$name] ) || empty( $_POST[$name] ) && '0' !== $_POST[$name];
if ( $tag->is_required() && $empty ) {
$result->invalidate( $tag, wpcf7_get_message( 'invalid_required' ) );
}
return $result;
}
This code should also go in your functions.php file just under the code for the custom CF7 tag.
Here the filter's first string $tag should match with the class that is being generated in the custom CF7 tag so if your custom tag->type = 'myCustomField' then the $tag of the filter must include the name, like so wpcf7_validate_myCustomField as well as the required version of it, wpcf7_validate_myCustomField*.
I hope that helps anyone else looking for this.
If you want even more of the options available from the backend of Contact Form 7 check the select.php file as it lays it out quite nicely on how to get each option and include it.
You can use [select*] to output a required drop-down menu.
[select* course-name include_blank "English" "Math"]
Check https://contactform7.com/checkboxes-radio-buttons-and-menus/
EDIT:
So you have your own shortcode [myCustomField]. To make two versions of your shortcode as [myCustomField] and [myCustomField*] you have to pass both shortcodes to your function as the following:
add_action( 'wpcf7_init', 'wpcf7_add_form_tag_mycustomfield' );
function wpcf7_add_form_tag_mycustomfield() {
wpcf7_add_form_tag( array( 'myCustomField', 'myCustomField*'),
'wpcf7_mycustomfield_form_tag_handler', array( 'name-attr' => true ) );
}
function wpcf7_mycustomfield_form_tag_handler( $tag ) {
$tag = new WPCF7_FormTag( $tag );
if ( empty( $tag->name ) ) {
return '';
}
$atts = array();
$class = wpcf7_form_controls_class( $tag->type );
$atts['class'] = $tag->get_class_option( $class );
$atts['id'] = $tag->get_id_option();
$atts['name'] = $tag->name;
$atts = wpcf7_format_atts( $atts );
$html = sprintf( '<your-tag %s></your-tag>', $atts );
return $html;
}
Then, you can use it:
[myCustomField course-name class:custom-field]
or
[myCustomField* course-name class:custom-field]
References:
https://contactform7.com/2015/01/10/adding-a-custom-form-tag
https://contactform7.com/2015/02/27/using-values-from-a-form-tag/

Resources