"get_current_user_id()" strict comparison with number fails - php

I've got a technical question to which I would like to have insights more than a solution.
I hooked a custom function to 'template_include' filter in WordPress functions.php as below to work on a page without it being watchable by anyone else.
function template_redirect( $template ) {
if ( $template === locate_template('single-ressource.php') && get_current_user_id() === 11 ) {
return $new_template = locate_template( array( 'single.php' ) );
}
return $template;
};
add_filter( 'template_include', 'template_redirect', 99 );
So if anyone who's not logged into my account go to a 'ressource' custom post type page, they see it with the standard single.php layout and not with the single-ressource.php layout.
The thing is, it doesn't work as is. I have to change the 11 integer in the strict comparison to '11' string to make it work (see edit), as below.
function template_redirect( $template ) {
if ( $template === locate_template('single-ressource.php') && get_current_user_id() === '11' ) {
return $new_template = locate_template( array( 'single.php' ) );
}
return $template;
};
add_filter( 'template_include', 'template_redirect', 99 );
I went to see the official documentation for the get_current_user_id() function and it seems that they use type casting to return either an integer or 0.
Furthermore, when I do a var_dump(get_current_user_id()) on my front-end, it returns int(11).
Anyone has an idea about why the second code works (see edit) and not the first one?
Edit
As #Bazaim pointed it out, I was just confused about the logic involved.
With the second code, the actual "single-ressource.php" I wanted to hide wasn't hidden to anyone because the logic behind the condition passed was flawed. I was redirecting only users with a user_id equal to a string '11' which is no one because user_id are integers.
The code below works perfectly.
function template_redirect( $template ) {
if ( $template === locate_template('single-ressource.php') && get_current_user_id() !== 11 ) {
return $new_template = locate_template( array( 'single.php' ) );
}
return $template;
};
add_filter( 'template_include', 'template_redirect', 99 );

Your user_id is 11 ?
You require to see single.php :
$template to be 'single-ressource.php' : right
get_current_user_id() to be 11 : wrong, you want the id not to be 11

Related

How to remove Wordpress' Gutenberg and use Classic Editor just in the front page?

I am creating a new WordPress Theme and would like to use the Classic Editor specifically on the front page. To achieve this, I plan to modify the functions.php file with a few lines of code instead of relying on a plugin.
I would like to maintain the Gutenberg editor for other pages and posts.
Despite trying different methods, I have not found a solution that worked. Or I am able to remove the Gutenberg Editor from all the pages, or not remove it at all.
That's my most recent try.
Does someone know what can I do?
Thanks a lot!!!
function use_classic_editor_on_front_page( $use_block_editor, $post_type ) {
if ( ! is_admin() && is_front_page() && 'page' === $post_type ) {
return false;
}
return $use_block_editor;
}
add_filter( 'use_block_editor_for_post_type', 'use_classic_editor_on_front_page', 10, 2 );
hope this helps,
add_filter( 'use_block_editor_for_post_type', 'use_classic_editor_on_front_page' );
function use_classic_editor_on_front_page( $use_block_editor ) {
if ( 'page' === get_option( 'show_on_front' ) && get_option( 'page_on_front' ) && get_the_ID() == get_option( 'page_on_front' ) ) {
$use_block_editor = false;
}
return $use_block_editor;
}

How to overwrite a theme function within a custom plugin?

To begin with, my problem:
I have a WooCommerce error on the W3C Validator platform.
I overwrite the file by redirecting the template path of WooCommerce for that specific file.
Problem:
The Wordpress Theme that I am currently using is also overwritting the same file as my Custom plugin, as a result the Theme's overwriting cancels out my plugin's overwritting functionality.
CODE:
Here's some of my code:
This is the function I add using the built in wordpress function add_filter() with high priority value of "1" plus the path of the file I am overwritting is... woocommerce/templates/single-product/add-to-cart/variable.php
function wc_locate_template( $template, $template_name, $template_path ) {
// Check if WooCommerce is present on the website
if ( empty( $template ) || ! is_callable( 'WC' ) || ( defined( 'WC_TEMPLATE_DEBUG_MODE' ) && WC_TEMPLATE_DEBUG_MODE ) ) {
return $template;
}
// Variables
$default_path = WC()->plugin_path() . '/templates/';
$plugin_path = untrailingslashit( plugin_dir_path( __FILE__ ) ) . '/templates/';
$template_new = str_replace( $default_path, $plugin_path, $template );
// Processing
if (
false !== strpos( $template, $default_path )
&& file_exists( $template_new )
) {
$template = $template_new;
}
// Output
return $template;
}
add_filter( 'woocommerce_locate_template', 'wc_locate_template', 1, 3 );
Questions:
How can I make sure that my plugin will overwrite the file of in such way or prority so that the theme's overwritting won't overlap it?
Useful links:
Woocommerce Link
W3C Validator Link
Wordpress Link
Thank you in advance for your time.
priority 1 means your function will be applied first, so any other function attached to the filter with a number higher than 1 will simply overwrite your function.
You need to put highest possible number to make sure your function will be the last one applied.
use PHP_INT_MAX to make your function the last one applied.
add_filter( 'woocommerce_locate_template', 'wc_locate_template', PHP_INT_MAX, 3 );
That's an example on how to override a woocommerce template with a plugin:
add_filter( 'woocommerce_locate_template', 'woo_custom_template', 1, 3 );
function woo_custom_template( $template, $template_name, $template_path ) {
global $woocommerce;
$_template = $template;
if ( ! $template_path )
$template_path = $woocommerce->template_url;
$plugin_path = untrailingslashit( plugin_dir_path( __FILE__ ) ) . '/templates/';
// Within passed path within the theme - this is priority
$template = locate_template(
array(
$template_path . $template_name,
$template_name
)
);
// Processing
if( ! $template && file_exists( $plugin_path . $template_name ) )
$template = $plugin_path . $template_name;
if ( ! $template )
$template = $_template;
//Output
return $template;
}
Then you should be able to reach your goal by copying the template you want to override in your plugin folder.
Example:
your_plugin/template/WooCommerce/single-product/add-to-cart/variable.php
Hooks and filter are modification which runs based on priority,
the highest the priority before its being called will be the its final output
Here's an example
Assuming I have this function
function youFree() {
$imFree = apply_filters('free_filter', 'I am free' );
return $imFree;
}
then I have all these filters with different priorities
add_filter('free_filter', function() {
return 'You are not 1';
}, 1);
add_filter('free_filter', function() {
return 'You are not 10';
}, 10);
add_filter('free_filter', function() {
return 'You are not 999';
}, 999);
add_action('init', function() {
add_filter('free_filter', function() {
return 'You are not init 999';
}, 999);
});
add_action('wp_footer', function() {
add_filter('free_filter', function() {
return 'You are not wp_footer';
}, 999);
});
Here is the output
if you call youFree() on wp_head
add_action('wp_head', function() {
echo '<pre>', print_r(youFree(), 1), '</pre>';
});
//the output is "You are not init 999"
//because the add_filter that runs on wp_footer did not take effect
//as the function is already called way higher specifically in wp_head
//and the final value is last filter being called thats added on init hook with 999 priority
but if you call that youFree() function on wp_footer
add_action('wp_footer', function() {
echo '<pre>', print_r(youFree(), 1), '</pre>';
}, 20);
//the output is "You are not wp_footer"
//as this was the very last filter before that function is called on wp_footer
So in your situation,
You have to determine at which point the theme do the modification and at which point the value is being called.
Then you need to inject your filter after your theme modifies it and before it was called by woocommerce. Usually, this is as easy as looking at where the theme calls the filter and adding a priority on your filter which is higher than whats on the theme filter.
but if your having a hard at where to inject it your best option is to find it using query monitor

Disable shortcode if status of value changes?

Looking to do enable or disable shortcode in a function, depending on a value. For instance, if someone says purchases a license key to use some shortcode on their site, I'd like to have the shortcode become disabled if they license expires. Example function I've been working on below:
my_premium_shortcodes(); // Fires early in my php file
function my_premium_shortcodes(){
$status = get_option( 'key_status' );
if( $status !== false && $status == 'valid' ) {
add_shortcode('shortcode_handle_1','shortcode_function_1');
add_shortcode('shortcode_handle_2','shortcode_function_2');
} else {
remove_shortcode('shortcode_handle_1','shortcode_function_1');
remove_shortcode('shortcode_handle_2','shortcode_function_2');
}
}
Any input on my approach or if the function should be handled in a separate way would be appreciated. As it stands, the shortcodes are working when everything is enabled, but stay enabled even after the 'status' changes to 'invalid'.
You should use the code in two different functions instead of one single function. Please review below code and implement into your site.
$status = get_option( 'key_status' );
if( $status !== false && $status == 'valid' ) {
//add a custom shortcode
add_action( 'init', 'my_add_shortcodes' );
function my_add_shortcodes() {
add_shortcode( 'myShortcode', 'my_shortcode_function' );
}
else{
//which can also remove
add_action( 'init', 'remove_my_shortcodes',20 );
function remove_my_shortcodes() {
remove_shortcode( 'myShortcode' );
}
Just wanted to post an update. The value of the status was apparently not properly being read by previous functions I had in my code. Essentially, just having my 'if' statement and removing the 'else' was all I needed to do.
So this works fine FYI:
function my_premium_shortcodes(){
$status = get_option( 'key_status' );
if( $status !== false && $status == 'valid' ) {
add_shortcode('shortcode_handle_1','shortcode_function_1');
add_shortcode('shortcode_handle_2','shortcode_function_2');
}
}
If the 'key_status' is actually being read, otherwise the shortcode was always firing.
Add shortcode function code into the function.php file or in the plugin file.
function my_add_shortcodes() {
// Add your code here
}
add_shortcode( 'myShortcode', 'my_shortcode_function' );
Use the below condition to call the shortcode in any file of your theme.
$status = get_option( 'key_status' );
if( $status !== false && $status == 'valid' ) {
echo do_shortcode('[myShortcode]');
}
I hope it will help you.

post_type filter for post does not exclude pages

I have following problem in Wordpress. I have this code in function.php which should make posts title on frontend from Yoast SEO title. Code works, however it has also impact on pages.
function set_my_seo_title($title, $id)
{
global $post;
$seo_title=get_post_meta($id, '_yoast_wpseo_title', true);
return ((!empty($seo_title)&&$post->post_type=='post') ? $seo_title : $title);
}
add_filter('the_title', 'set_my_seo_title', 15, 2);
The problem is with condition post_type=='post'. It looks like there is some bug in Wordpress, but may be I am doing something wrong.
Important: I have to admit I am not good developer. This code is from other question. If you know solution for this please post your full code variant. Thank you in advance.
You could try get_post_type() instead...
function set_my_seo_title( $title, $id ) {
$seo_title = get_post_meta( $id, '_yoast_wpseo_title', true );
return ( ( ! empty( $seo_title ) && get_post_type( $id ) == 'post' ) ? $seo_title : $title );
}
add_filter( 'the_title', 'set_my_seo_title', 15, 2 );

How to display the comments_template with a shortcode, in Wordpress?

I managed to display the comment_form with a shortcode (while removing it from the default location) using the code below:
`add_shortcode( 'wpse_comment_form', function( $atts = array(), $content = '' )
{
if( is_singular() && post_type_supports( get_post_type(), 'comments' ) )
{
ob_start();
comment_form();
print( '<style>.no-comments { display: none; }</style>' );
add_filter( 'comments_open', '__return_false' );
return ob_get_clean();
}
return '';
}, 10, 2 );
Code suggested by birgire in this answer: https://wordpress.stackexchange.com/a/177289/26350
For more clarity, here is where I want to get: I need to display both the comments form and the comments list through shortcodes and in different locations. I managed to mimic the same code above to display the comments_template (and later editing the comments.php to remove the comment_form from it, since what I really need to display is the comments list) but the comments list displays 2x, one in the shortcode location and also at the bottom of the post (default location). I tried to use the same code to display the wp_list_comments independently but without success.
If you do not provide an array of comments wo wp_list_comments, then it expects to find that a query has already been done (i.e. in the loop).
If you want to display comments for a post independent of the loop, you can use something like:
$comments = get_comments( array( 'post_id' => $id ) );
wp_list_comments( array( 'per_page' => how many to show ), $comments);
So to put it in a shortcode you would do something like (not tested):
add_shortcode( 'wpse_comment_list', function( $atts = array(), $content = '' )
{
if( isset($atts['id']) && post_type_supports( $atts['id'], 'comments' ) )
{
ob_start();
$comments = get_comments( array( 'post_id' => $atts['id'] ) );
wp_list_comments( array( 'per_page' => how many to show ), $comments);
return ob_get_clean();
}
return '';
}, 10, 2 );
and you would invoke it with [wpse_comment_list id="33"] (or whatever the id is).
I managed to arrive at the result that I needed but partly through deleting on my child-theme the parts that I couldn't remove through code.
I mimicked the code used to shortcode-display the comment_form (above in the question) to shortcode-display the comments_template (here below). It displayed it where I needed but it didn't remove it's "ghost" from the bottom of the post like the previous code did for the comment_form. So I copied single.php to my child-theme and deleted all this:
<?php
`// If comments are open or we have at least one, load up
the comment template
if ( comments_open() || '0' != get_comments_number() )
comments_template( '', true );
?>
It worked. Not sure it's the best way though and I'm curious about it. I won't need comments at the bottom of posts anymore; my comment form is a different form now and has different locations too, in case that is the only issue.
Here is the code I used to shortcode-display the comments_template. I needed it to display only the comments and not the form, so I removed the comments_form call from the comments.php in my child-theme.
add_shortcode( 'wpse_comments_template', function( $atts = array(), $content = '' )
{
if( is_singular() && post_type_supports( get_post_type(), 'comments' ) )
{
ob_start();
comments_template();
print( '<style>#comments-title { display: none; }</style>' );
return ob_get_clean();
}
return '';
}, 10, 2 );
If you are running the [wpse_comments_template] shortcode before this part in your theme:
<?php
if ( comments_open() || '0' != get_comments_number() )
comments_template( '', true );
?>
then it's attempting to use:
add_shortcode( 'wpse_comments_template', function( $atts = array(), $content = '' )
{
if( is_singular() && post_type_supports( get_post_type(), 'comments' ) )
{
ob_start();
comments_template();
add_filter( 'comments_open', '__return_false' );
add_filter( 'get_comments_number', '__return_zero' );
return ob_get_clean();
}
return '';
}, 10, 2 );
but this might interfere with comment related stuff that comes later, for example in the sidebar.
So it would be more accurate to use:
/**
* Display the comment template with the [wpse_comments_template]
* shortcode on singular pages.
*
* #see http://stackoverflow.com/a/28644134/2078474
*/
add_shortcode( 'wpse_comments_template', function( $atts = array(), $content = '' )
{
if( is_singular() && post_type_supports( get_post_type(), 'comments' ) )
{
ob_start();
comments_template();
add_filter( 'comments_open', 'wpse_comments_open' );
add_filter( 'get_comments_number', 'wpse_comments_number' );
return ob_get_clean();
}
return '';
}, 10, 2 );
function wpse_comments_open( $open )
{
remove_filter( current_filter(), __FUNCTION__ );
return false;
}
function wpse_comments_number( $open )
{
remove_filter( current_filter(), __FUNCTION__ );
return 0;
}
and you wouldn't have to remove any code from your theme.
I tested this on the Twenty Fifteen theme and it seemed to work as expected.

Categories