How can I set a cookie based on page ID in wordpress? - wordpress

Currently trying to have wordpress set a cookie based on particular pages.
I can set a general cookie from my functions file, and calling add_action() on the init hook.
/* functions.php */
function setCookies(){
global $post;
setcookie('test', 'it works');
var_dump($post->ID);
}
add_action( init, setCookies(), 10);
The var_dump is returning NULL.
Is there a hook that will execute in time to set a cookie, but late enough to have information from global $post;

The $post variable isn't set until you're inside the loop. Most themes have already generated output by the time you get there, so you won't be able to ever use that to set a cookie.
However, you should be able to hook into the wp action after the query is returned and set a cookie using your own custom loop. Try something like this:
function setCookies() {
global $wp_query;
if ($wp_query->have_posts()) {
$post_id = $wp_query->current_post;
setcookie('post_id', $post_id);
}
$wp_query->rewind_posts();
return;
}
add_action( 'wp', 'setCookies', 10);
See the Actions Run During a Typical Request and the WP_Query Class Reference in the codex.

Related

$wp_query is returning nothing

I have the following code in my plugin file:
// SET UP REWITE RULES FOR LISTING PERMALINKS //
function my_rewrite_tags() {
add_rewrite_tag('%listingId%', '([^&]+)');
}
add_action('init', 'my_rewrite_tags', 10, 0);
function my_rewrite_rules() {
add_rewrite_rule('^listing/([^/]*)/?','index.php?pagename=listing&listingId=$matches[1]','top');
}
add_action('init', 'my_rewrite_rules', 10, 0);
This idea is that I have a page called "Listing" with the permalink "listing" and I want to be able to have the listing's ID number after it (i.e., /listing/12345/)
I then have a shortcode running on the "Listing" page
// SHORTCODE FOR SINGLE LISTING PAGE //
function my_single_listing(){
ob_start();
include('templates/single-listing.php');
return ob_get_clean();
}
add_shortcode('listing','my_single_listing');
...and the first thing it does is try to get that listing ID with the code:
$listingId = $wp_query->query_vars['listingId'];
I've done this with other plugins I've written in the past, but in this case it's decided to not work. In fact, if I enter the code:
print_r($wp_query);
I get absolutely nothing returned from it at all. (All other content on the page is displaying fine though.)
Any ideas?
Your issue with $wp_query being blank might be due to it not being accessed as a global variable. Prefacing it with a global declaration will allow it to access the global query:
global $wp_query;
print_r( $wp_query )
The issue with the listing ID not being picked up has to do with it not being declared as a possible custom query var. WordPress requires you to declare them before it loads them into the global wp_query for the page (presumably for security). $_GET was able to access them since that bypasses WordPress and just uses it with PHP.
function so_71685702_add_query_vars( $query_vars ) {
$query_vars[] = 'listingId';
return $qvars;
}
add_filter( 'query_vars', 'so_71685702_add_query_vars' );
Once you've got that, $wp_query->query_vars( 'listingid' ) should return a value.
Here's the query_vars hook information page, and the get_query_var hook information page which might be useful for further reading - might cover some things you'll run into based on the way you're setting up custom rewrites and query vars.

WooCommerce Registration Shortcode - Error messages problems

I am currently creating a widget to display the registration form on a WordPress website that uses WooCommerce. For now, I only have 3 basic fields which are email, password, repeat password. I'm looking forward to add more WooCommerce fields, but want to solve that problem before jumping to the next step.
I'm having some problems with the messages output (wrong password, account already exists, etc).
I searched on the web and there was no shortcode already built for WooCommerce registration, beside their registration page. So I went ahead and created a shortcode, with a template part.
function custom_register_shortcode( $atts, $content ){
global $woocommerce;
$form = load_template_part('framework/views/register-form');
return $form;
}
add_shortcode( 'register', 'custom_register_shortcode' );
This is a snippet I use to get the template part inside a variable, since the default function would "echo" the content instead of "returning" it.
function load_template_part($template_name, $part_name=null) {
ob_start();
get_template_part($template_name, $part_name);
$var = ob_get_contents();
ob_end_clean();
return $var;
}
So, the problem is, when I call woocommerce_show_messages or $woocommerce->show_messages(); from my template part, nothing is showing, or if it is, it shows at the top of the page.
I did try to put the calls inside my shortcode function:
function custom_register_shortcode( $atts, $content ){
global $woocommerce;
$woocommerce->show_messages();
$form = load_template_part('framework/views/register-form');
return $form;
}
add_shortcode( 'register', 'custom_register_shortcode' );
Doing so, the message output inside the <head> tag, which is not what I want.
I tried to do the same trick with ob_start(), ob_get_contents() and ob_clean() but nothing would show. The variable would be empty.
I also did try to hook the woocommerce_show_messages to an action as saw in the core:
add_action( 'woocommerce_before_shop_loop', 'woocommerce_show_messages', 10 );
For something like:
add_action( 'before_registration_form', 'woocommerce_show_messages');
And I added this in my template-part:
<?php do_action('before_registration_form'); ?>
But I still can't manage to get the error messages show inside the box. It would always be inserted in the <head>
I will share final solution when everything is done.
Thanks for your time,
Julien
I finally got this working by hooking a custom function to an action which is called in my header.php
I guess hooking functions inside template part does not work as intended.
In header.php, I got this:
do_action('theme_after_header');
And here's the hooked function. Works perfectly.
function theme_show_messages(){
woocommerce_show_messages();
}
add_action('theme_after_header', 'theme_show_messages');
However, I will look into 'unhooking' the original show message function since it might show twice. Need to test some more ;)
You can also just use the [woocommerce_messages] shortcode in your template where you want it displayed
Replying to a bit of an old question, but you can also try the following:
$message = apply_filters( 'woocommerce_my_account_message', '' );
if ( ! empty( $message ) ) {
wc_add_notice( $message );
}

How to edit a post dynamically in wordpress plugin

I have created a small wordpress plugin that displays a list of people in a page via shortcode.
When the user clicks on one of the names from the list, a query_var gets set and my plugin catches the $_GET with the specific id of the person the user just clicked. All very well until now.
My problem is that now I want to display a page with the details (for the clicked element) but I dont seem to be able to edit the content or post that gets to the page and it returns me to the page with the list of people.
My question is how do I edit the post? I have tried adding a add_filter('the_content','my_func') to this, but this does not work since this hook is probably already passed.
I can access the post directly via get_content() or get_post(), but I dont seem to be able to make the page populated new data.
In other words... this does nore seem to work
$fid = $_GET['fid'];
global $wpdb;
$sql = "select * from fighters where fighter_id = {$fid} limit 1";
$fighter = $wpdb->get_row($sql);
$html = $this->_getFighterPageLayout($fighter);
$post = get_post();
$post->post_content = $html;
$post->title = 'test';
$post->private = false;
// or even just global $content = $html;
What am I doing wrong and what ways do I have to edit/update the content/post?
You have to use the hooks of Wordpress to update the content. This works with the add_filter function
Try something like this, it should works
function mytheme_content_filter( $content ) {
// Do stuff to $content, which contains the_content()
// Then return it
return $content;
}
add_filter( 'the_content', 'mytheme_content_filter' );

Getting hold of metadata when creating a post in WordPress

I am using the save_post action to inspect a metadata field in a custom post and take some action on that value. This is the essential guts of how I am doing it:
add_action('save_post', 'my_save_post');
function my_save_post($post_id)
{
// Check if not autosaving, processing correct post type etc.
// ...
// Get the custom field value.
$my_field_value = get_post_meta($post_id, 'my_field', true);
// Do some action
// ...
}
This works fine when updating the post through the admin page. However, when first creating the post, the my_field_value is always empty. The field does get saved correctly, but this action trigger does not seem to be able to see it, nor any other custom field values.
I would like the action to be performed on all posts of this type created, and I will be importing many through the CSV Imported plugin. Even then, the custom fields do get imported correctly, and the action trigger does get fired for each row imported, but the save_post action still cannot see the custom field value.
So far as I can see from documentation, the post has already been created by the time this action fires, so I should always be able to see that custom metafield.
The answer, it seems, is in the order in which things happen. When creating a post from a form, the custom fields are all collected by the appropriate actions and added to the post before my save_post action fires. This means my trigger is able to see those custom field values.
When importing from CSV, the basic post is created first, and then the custom metafields are added. The save_post trigger fires on the first creation, before the metafields are added, and so the custom field data is not visible to the save_post action.
My solution was to catch the updates of the metadata using the updated_post_meta and added_post_meta actions as well as the save_post action:
add_action('updated_post_meta', 'my_updated_post_meta', 10, 4);
add_action('added_post_meta', 'my_updated_post_meta', 10, 4);
function my_updated_post_meta($meta_id, $post_id, $meta_key, $meta_value)
{
// Make sure we are handling just the meta field we are interested in.
if ($meta_key != 'my_custom_field') return;
if (wp_is_post_revision($post_id)) return;
if (get_post_type($post_id) != 'my_post_type') return;
if (trim($meta_value) == '') return;
// Do my custom task (linking this post to a parent post in a different
// post type). This is the same task performed by the save_post action.
my_link_product_track($post_id, trim($meta_value));
}
That is essentially what I do, and it seems to work well. I do encapsulate all the above into a custom class in the theme, and don't recommend using global scope variables as shown here, but this is just to show the method.
You should look at using $post->ID instead of $post_id -
$my_field_value = get_post_meta($post->ID, 'my_field', true);
get_post_meta in the Codex
EDIT:
Could you do something like this?
if($post->ID == ''){
$pid = $post_id;
} else {
$pid = $post->ID;
}
//$pid = $post->ID or $post_id, whichever contains a value
$my_field_value = get_post_meta($pid, 'my_field', true);
something that looks for a value in $post->ID and $post_id, and uses whichever one isn't blank?

Custom post type functions.php if statement on action

I am using developing a child theme for Woothemes' Canvas.
I am trying to use functions.php in the child theme to only use actions on my custom post type.
This code doesn't seem to be working:
add_action( 'woo_post_inside_after', 'my_geo_mashup' );
function my_geo_mashup() {
echo GeoMashup::map();
if ($post->post_type == 'listings') {
//My function
}
}
add_action( 'woo_post_inside_before', 'listings_nivo' );
function listings_nivo() {
echo do_shortcode('[nivo source="current-post" ]');
if ($post->post_type == 'listings') {
//My function
}
}
So, I'm unsure how to get the above to work properly and only show these items on the custom post type, or only for the custom post type template single-listings.php (as I only want the map and slider to show on the actual post, not on the blog page (archive.php)
Rather than making the entire $post object global, you can just make $post_type global instead. Ex below.
I'm not exactly sure where that function is being loaded, but make sure you hook somewhere within the post. If the action is before, as far as I know and from experience, the post variable will be null.
Just as a test, try running the action in wp_footer Ex. add_action( 'wp_footer', 'listings_nivo' );
See if that yeilds any results.
if echoing var_dump($post) is still null, well, not sure where to go from there.
So you can try running the below, then run the action in the appropriate place if it works:
function listings_nivo() {
echo do_shortcode('[nivo source="current-post" ]');
global $post_type;
// Diagnostic purposes
echo var_dump($post_type);
if ($post_type == 'listings') {
//My function
}
}
add_action( 'wp_footer', 'listings_nivo' );
Check your error log or turn wp_debug to true in your wp-config.php file if nothing else to see if anything else is going on.
Best of luck!
Inside your function, try adding global $post;. Then to see what you are getting with $post->post_type echo it out to the screen. As long as this gives you "listings", your code should work. If not, there's probably another issue at play.

Resources