Wordpress / Woocommerce Hook into a Function - wordpress

I appreciate questions similar to this have been asked before but the answers I've tried aren't doing what I need.
Basically,
I have this file in the woocommerce plugin folder structure:
wp-content\plugins\woocommerce\includes\wc-coupon-functions.php
Inside the file is the following function:
function wc_get_cart_coupon_types() {
return (array) apply_filters( 'woocommerce_cart_coupon_types', array( 'fixed_cart') );
}
I need to override it so it returns an additional item in the array but nothing I've tried has worked. I've tried:
Creating the same file in my custom theme file
hooking the function in my functions file with the following code:
function woocommerce_coupon_get_cart_coupon_types()
{
return (array) apply_filters( 'woocommerce_cart_coupon_types', array( 'fixed_cart', 'custom_discount' ) );
}
add_filter('wc_get_cart_coupon_types', 'woocommerce_coupon_get_cart_coupon_types',10, 1);
Any other suggestions would be greatly appreciated, also..... I've made the change directly in the file and it definitely works. Thanks

Your #2 approach is sort of how to do it, but you're essentially caught in a loop situation the way you did it.
You need to do it this way:
function wpso59974749_woocommerce_coupon_get_cart_coupon_types( $data ) {
$data[ 'your_new_key_here' ] = 'your new value here';
return $data;
}
add_filter('woocommerce_cart_coupon_types','wpso59974749_woocommerce_coupon_get_cart_coupon_types',10, 1);
You shouldn't add the apply_filter back in your function, as it would get stuck in a loop - essentially refiltering itself over and over.
I prefixed your function so if there is another woocommerce_coupon_get_cart_coupon_types function, it won't conflict.

Related

How do I add my class the earliest possible?

I am using the following code to add my class “noTypo”:
function prefix_register_block( $blocks ) {
// 'my_block' corresponds to the block slug.
$blocks['wpgb_custom_title'] = [
'name' => __( 'WPGB Custom Title', 'text-domain' ),
'render_callback' => 'prefix_my_block_render',
];
return $blocks;
}
add_filter( 'wp_grid_builder/blocks', 'prefix_register_block', 10, 1 );
// The render callback function allows to output content in cards.
function prefix_my_block_render() {
// Get current post, term, or user object.
$post = wpgb_get_post();
// Output the post title.
echo '<span class="noTypo">' . esc_html( $post->post_title ) . '</span>';
}
But it seems that this code above is adding the class later than this code:
function add_notypo_to_title( $title ) {
return "<span class='noTypo'>$title</span>";
}
if (! is_admin() ) {
add_filter( 'the_title', 'add_notypo_to_title', 10, 1 );
}
Both codes add the class successfully, yet the plugin that should use the class for dewidowing – wpTypography -, does not see the class if it’s added with the first code, but it does see the class when it’s added with the second code.
The conclusion is that the class is not available for the plugin at the time it’s processing my content:
add_filter('wp_grid_builder/the_content', [ 'WP_Typography', 'process' ] );
My question is how do I modify the first code so that the class will be added at the earliest possible time, so that at the time wpTypography is processing the content, it would already be available?
The wpTypography plugin does not inspect the final HTML, but it looks for the class at a much earlier stage.
It seems that when I am hooking into the_title in a global function, the class is added earlier.
Is there a way to make my first function global?
Would that make it add the class earlier?
It makes sense that native WP code like the_title runs earlier than plugin code.
I tried to add global $post; into my function, but it will not make the class to be added earlier.
Can I troubleshoot this with Query Monitor to see when are these functions running? And how do I do that?
Does anyone have any other ideas?
According to the wpTypography developer:
what matters is whether the string ultimately passed to
WP_Typography::process as its first parameter contains the element
with the class
How do I verify if the string passed is the first parameter of the process?
Thanks in advance.

hijack get_template_part via plugin

I'm trying to do a plugin that will change the behavior of a theme.
In the theme file I have a get_template_part('libs/templates/user_menu');
I want to make my plugin to "force" the get_template_part return another slug file (a path to a file in plugin folder).
So far this is my code inside the plugin:
function wpse21352_template_part_cb( $slug )
{
if(slug == 'user_menu') {
return WP_PLUGIN_URL.'/'.$slug;
} else {
return $slug;
}
}
do_action( "get_template_part_user_menu", 'user_menu' );
add_action( 'wpse21352_template_part_cb', 'get_template_part_user_menu', 10, 1 );
First of all, get_template_part does not return anything. It loads a file from your theme based on the parameters you pass to it. The function does not support filtering, which means you can not actually overwrite what is outputted by get_template_part.
The only thing the action get_template_part_[slug] allows you to do is output something before the theme file is loaded. For example, using
function myplugin_before_login( $slug, $name ) {
echo 'Example';
}
add_action( 'get_template_part_login', 'myplugin_before_login', 10, 2 );
would output "Example" before the loading the theme file when calling get_template_part( 'login' );.
Actions and filters
In general, however, I believe you might misunderstand how actions and filters work. The WordPress Codex offers extensive information on their use and usage.

Wordpress Plugin: Show html only on standard page and not in admin area

I'm writing a plugin and I need to display a piece of text in the WP page, but not in the admin area. How can I do so?
I tried this in the construct:
add_action( 'init', array( $this, 'initPage' ) )
and then:
public function initPage() {
echo 'hello';
}
but the text is displayed also in the admin area. Is there a way to do this? It would be the opposite of the action admin_init I assume.
Proper way to handle it: is_admin()
http://codex.wordpress.org/Function_Reference/is_admin
if(is_admin()) { // do nothing } else {
// function you want to execute.
}
I solved this by adding it to a shortcode action. Like this:
add_shortcode( 'myPlugin', array( $this, 'shortcode' ) );
and:
public function shortcode( $atts ) {
return 'hello';
}
With the above code, 'hello' will only display on the front-end. Not sure if that's the cleaner way to do it, but does the job.
There is no "front-end-only" version of init, however you probably don't want to be doing any output at the init action anyway.
What exactly are you trying to do? Usually, you use an action hook for specific types of things, and causing output very early at something like "init" is rare and weird.

How can I select books randomly in Now Reading wordpress plugin?

I am using 'Now Reading' plugin in a wordpress project. In plugin's sidebar template I am using this query:
while( have_books('status=read&orderby=finished&num=2') ) : the_book();
to select 2 books.
What parameter should I pass to make it random? I tried with 'order=rand' and 'rand=true' but it did not work.
Any help will be appreciated!
Thanks in advance..
A random function doesn't actually exist. I have used this code, in my themes functions.php to allow random order before - not sure if it'll work in this situation, but worth a try.
Add this to your themes functions.php file:
function query_random_posts($query) {
return query_posts($query . '&random=true');
}
class RandomPosts {
function orderby($orderby) {
if ( get_query_var('random') == 'true' )
return "RAND()";
else
return $orderby;
}
function register_query_var($vars) {
$vars[] = 'random';
return $vars;
}
}
add_filter( 'posts_orderby', array('RandomPosts', 'orderby') );
add_filter( 'query_vars', array('RandomPosts', 'register_query_var') );
Then try this in your sidebar file:
while( have_books('status=read&orderby=finished&num=2&random=true') ) : the_book();
If not, my only other suggestion would be to get the 10 latest books, add them all to a new array, and then shuffle that array. May be a bit bloated though.

Dynamic shortcodes and functions in WordPress

I am having a bit of an issue with autogenerating shortcodes, based on database entries.
I am able to get a normal shortcode working i.e:
function route_sc5() {
return "<div>Route 5</div>";
}
add_shortcode('route 5','route_sc');
and the following shortcode to activate it would be [route 5]
This works. But what I need is the shortcode to be produced for each database entry. something like:
$routes = $wpdb->get_results( $wpdb->prepare("SELECT * FROM wp_routes") );
foreach($routes as $route)
{
function route_sc$route->id () {
return "<div>Route $route->id</div>";
}
add_shortcode('route $route->id','route_sc$route->id');
}
The above is just an example of how I want it to work. Not literally the code I am using. How would I go about achieving this? ):
Thanks.
Here's an example of dynamic shortcode callbacks using PHP 5.3 anonymous functions:
for( $i = 1; $i <= 5; $i++ ) {
$cb = function() use ($i) {
return "<div>Route $i</div>";
};
add_shortcode( "route $i", $cb );
}
I have to ask, though: can you just accomplish what you need to do using shortcode arguments? ie. [route num=3]. Then you could just have one handle_route() function and one [route] shortcode, which may simplify things.
Also, while technically you can include a shortcode with a space in the name, I think it creates a confusing ambiguity. If you decide you need specific shortcodes for each route, I would recommend "route5" or "route-5" rather than "route 5."
Thanks guys, finally got it working. here is the code for any1 who may need it in the future:
function route_sc($atts, $content = null) {
extract(shortcode_atts(array(
'num' => '',
'bg' => '',
'text' => '',
), $atts));
global $wpdb;
$bus = $wpdb->get_row( $wpdb->prepare("SELECT * FROM wp_route WHERE id = '$num'") );
return "<div class='".$bus->text_colour."' style='background-color:".$bus->bg_colour."'>".$bus->route_id."</div></div>";
}
add_shortcode('route','route_sc');
with the shortcode at [route num="5a"]
Dynamic function names are not possible in PHP.
But you could try eval.
eval('function route_sc'.$route->id.' () { return "<div>Route '.$route->id.'</div>"; }');
Go about it a different way: Shortcodes can take parameters. So instead of [route 5] do [route rt="5"]. This way your shortcode processing function stays generic and the part that changes is meant to be dynamic. It also means that if an unexpected shortcode is encountered during the page load you can handle it properly instead of WordPress just stripping the code and replacing it with nothing.
See here for more info: http://codex.wordpress.org/Shortcode_API

Resources