WordPress - Storing URL in transient is not constant - wordpress

I need to store current URL in transient, so I can access it for later use (when I need to link back to that page from search page).
Code:
if(!is_page_template('search.php')) {
set_transient( 'last_url', $current_url, 60*60 );
}
So this code should save current url of current page, until we are on search page.
However, once I click on the search page, 'last_url' will become domain.tld/search. I have no idea why is that happening when I explicitly have the rule if(!is_page_template('search.php'))
However, my temporary solution is to check if there is also word search in URL, and if there isn't then create transient, like:
if(!is_page_template('search.php')) {
if(stripos($current_url, 'search') === false) {
set_transient( 'shop_last_url', $current_url, 60*60 );
}
}
While this solution works, its the bad one since search page have different slug - for example if there are several languages...
I have also tried to use cookies and sessions without any luck.

If your theme doesn't uses default WordPress queries ($wp_query) then the functions such as is_page_template,get_page_template_slug would not work properly.
You can see it in corresponding Core code here.
So, for your current case you can use global template variable instead.
if (basename($GLOBALS["template"])=='search.php'){
set_transient( 'last_url', $current_url, 60*60 );
}
or
if (basename(get_page_template())=='search.php'){
set_transient( 'last_url', $current_url, 60*60 );
}

Related

Appending parameter to URL to solve issue with Page Caching and Tax Toggles

I have a WooCommerce website which uses a plugin called "Booster for WooCommerce" primarily for their "Tax Display" module. This plugin enables us to have a button in the header which allows the customer to switch between inc and exc VAT. The default setting is including tax.
The problem I'm encountering now is when I enable page caching in W3 Total Cache, the plugin is caching the first visit to a shop or product page along with the prices and then the next person to visit that page sees pricing based on the first user's tax toggle setting, not their own.
I can think of a few solutions to this in varying complexity but after noticing that the booster plugin sets a session variable via:
WC()->session->set('wcj_toggle_tax_display',( 'incl' === $current_value ? 'excl' : 'incl' ));
I'm wondering if there's a simple fix where I could simply hook in just before page load and if that session variable is set to excl, then set a URL parameter such as "?vat=false". Which I'm assuming would then cache as it's own unique URL and solve the problem.
I'm just not sure which hook would work for appending the parameter to the URL and my searches are getting me nowhere.
I've scoured over various solutions to this issue for days now, so a simple fix like this would be a godsend, I'm just not 100% sure how possible it is.
Any help on this would be greatly appreciated!
Thanks,
Jack
So far, the following code seems to have solved this problem but I'm still testing further with W3 Total Cache.
// Add URL parameter vat=false if tax toggle set to excl
function custom_redirect_append_url_params() {
if (is_woocommerce()) {
$toggle_status = wcj_session_get( 'wcj_toggle_tax_display' );
if (empty($toggle_status)) $toggle_status = 'incl'; //default value = incl
//if vat isn't set as a query var && toggle status is set to excl then redirect
if(!isset($_GET['vat']) && $toggle_status === 'excl') {
//do your redirect here with wp_redirect()
wp_redirect( add_query_arg( 'vat', 'false', $_SERVER['REQUEST_URI'] ));
exit; //prevent wordpress continuing to load templates
}
elseif($_GET['vat'] === 'false' && $toggle_status === 'incl') {
wp_redirect( add_query_arg( 'vat', 'true', $_SERVER['REQUEST_URI'] ));
exit; //prevent wordpress continuing to load templates
}
}
}
add_action('template_redirect','custom_redirect_append_url_params');

Give access to only two (/home, /inbox) page for a particular user with specific role in wordpress

I want to give only two page (/home, /inbox) access to my user with role "Vendor", if user tries to access other pages than it will automatically redirect to "/inbox" page, I put the below code to achieve the functionality but after adding this to function.php, site again n again redirect and finally dies with message "Page isn't properly redirected". please suggest what is wrong with my tried code or any other solution.
function vendor_redirect() {
global $post;
if(current_user_can('Vendor') && !in_array($post->slug,array("home","inbox"))) {
wp_safe_redirect('/inbox');
}
}
add_action('template_redirect', 'vendor_redirect');
The main issue the way I tried to get the page slug, the correct way to get the slug is "$post->post_name". also I put exit after wp_safe_redirect as well because codex suggest that:
function vendor_redirect() {
global $post;
if(current_user_can('Vendor') && !in_array($post->post_name,array("home","inbox"))) {
wp_safe_redirect(get_permalink(get_page_by_path( 'inbox' )));
exit;
}
}
add_action('template_redirect', 'vendor_redirect');

Custom Post Type Action Hook / Transients

This question is in regards to a plug-in I'm developing.
I'm trying to fire a function each time a custom post type called "Product" is added or edited. In particular, I need a hook that fires before the meta boxes load on the add/edit page, but that only fires on that "Product" custom post type's edit page.
The function that will fire makes an API request, and caches the response in a transient.
The reason for the action hook is because in my current code, when the transient has expired, the add/edit page is broken during the first page load. However if you refresh the page after that, it shows up as intended. I'm fairly certain this is happening because the current conditional statement that checks the transient is located inside of the function that generates the meta box. So my theory is if I can set up an action hook to check the transient before the meta box is generated, it might solve the problem.
However I've got a second theory that the problem is being caused because of the time it takes to make the API request and return the response is longer than the time it takes for the page to load. So if there is an action hook that will delay page loading until the function finishes executing it would be an ideal solution, but I don't believe such an action hook exists. I'm not even certain if such a delay is possible.
I'd really appreciate any help or alternative suggestions you guys might have. Thanks for your time guys.
Code Example:
add_action( 'edit_product', 'llc_hook_campaign_find_active' );
function llc_hook_campaign_find_active() {
if (!$t_campaign_find_active){
limelight_cart_campaign_find_active();
return false;
}
}
Since you are using an action hook, it is not waiting for your API response.
Try using a filter hook instead.
Try using wp_insert_post_data
function filter_handler( $data , $postarr ) {
//make your API call, get the response and store it in post meta or data wherever you want
$response = 'your API response';
//e.g. update_post_meta($postarr['ID'], 'meta_key', $response); OR
//$data['post_content'] = $response;
return $data;
}
add_filter( 'wp_insert_post_data', 'filter_handler', '99', 2 );
In your case, following should work -
add_filter( 'wp_insert_post_data', 'llc_hook_campaign_find_active', '99', 2 );
function llc_hook_campaign_find_active( $data , $postarr ) {
if (!$t_campaign_find_active){
limelight_cart_campaign_find_active();
return $data;
}
}
I was able to make the API request before the meta boxes loaded on the Admin Add/Edit screen by using the action filter edit_form_top. That particular action hook is fired as soon as the Add/Edit page for any post/page/custom post type is loaded. In order to narrow it down so that the function only fires on the Add/Edit screen for my "product" custom post type, I used get_current_screen() along with an if statement.
add_action('edit_form_top', 'llc_hook_campaign_find_active');
function llc_hook_campaign_find_active() {
//Fetch current screen information
$screen = get_current_screen();
//Check if post type is "product"
if($screen->post_type == "product") {
//API Request that checks for an existing transient
$t_campaign_find_active = get_transient('campaign_find_active');
if (!$t_campaign_find_active){
limelight_cart_campaign_find_active();
return false;
}
}
}
Works like a charm.

Wordpress: Plugin for simple user profile pages

In WordPress, I am aware that tld.com/author/username exists for authors, but I am looking for a public user profile page for non-authors. I want to setup a simplistic "favorite's list" for members on my site. Users will create an account, and add posts they like. They don't need access to wp-admin.
I'm looking for something simple like tld.com/user/username -- not /user/?uid=1. Nice and "pretty". Just like how WordPress handles /author/admin, or /author/username.
I would also like to keep /authors preserved so that's accessible too.
I have tried many plugins like WordPress-Users, but it's not a "pretty" URL, also have tried complicated plugins like Members, profile-builder, wp-user-frontend.
I found the answer to this from #bybloggers answer found here. https://wordpress.stackexchange.com/a/58793/12920
I modified his code very slightly to tailor it to my needs, but this is the code that worked for me and was exactly what I was looking for:
// Create the query var so that WP catches the custom /member/username url
function userpage_rewrite_add_var( $vars ) {
$vars[] = 'member';
return $vars;
}
add_filter( 'query_vars', 'userpage_rewrite_add_var' );
// Create the rewrites
function userpage_rewrite_rule() {
add_rewrite_tag( '%member%', '([^&]+)' );
add_rewrite_rule(
'^member/([^/]*)/?',
'index.php?member=$matches[1]',
'top'
);
}
add_action('init','userpage_rewrite_rule');
// Catch the URL and redirect it to a template file
function userpage_rewrite_catch() {
global $wp_query;
if ( array_key_exists( 'member', $wp_query->query_vars ) ) {
include (TEMPLATEPATH . '/user-profile.php');
exit;
}
}
add_action( 'template_redirect', 'userpage_rewrite_catch' );
After this was in my functions.php file, I had to re-save my Permalinks.
Sometimes re-saving the permalinks didn't finish the job 100% and browsing to www.mysite.com/member/username would 404, so I had to manually flush the rules by putting this into my functions.php and loading my site once. Then removing it so I don't run it every time the site loads, since that's unnecessary overhead.
// Code needed to finish the member page setup
function memberpage_rewrite() {
global $wp_rewrite;
$wp_rewrite->flush_rules();
}
add_action('init','author_rewrite');
I don't know if you will find this one, at least not for free. Have you checked out WPMU? I started writing a membership plugin a few months ago but never completed it and am now doing it in Symfony. Most WordPress membership plugins are either too complex to use or don't provide the features you need.
You should spec out what you need an get a local dveloper to build it for you, you might even be able to sell it if you do a good job.

Hide link to a Views' view if the view is empty

I have a Drupal 6.14 site with Views module. I have a view and on the primary links I put a link to the view.
There is a way to hide the link in the primary menu only if the view is empty?
You could probably do this either via a theme or module implementation of preprocess_page (THEMENAME_preprocess_page(&$vars) or MODULENAME_preprocess_page(&$vars)), but mac above is correct in that views are not known to be empty or not until they are run, so there will be a performance hit.
Within the function, you should have access to the structured primary links array, so you can run the view:
$view = views_get_view('view_name');
// Swap out 'default' for a different display as needed. Also, $args are arguments, and can be left out if not applicable.
$output = $view->preview('default', $args);
if (empty($view->result)) {
// The view has no results, alter the primary links here to remove the link in question.
}
I am ready to be contradicted any moment as I never implemented anything like that, however I am under the impression that since views are essentially queries against the DB, you can't actually know if a view is empty until you actually invoke it.
Consider that - given you are speaking about primary links (shown on nearly every page of your site) this might be a serious performance hit, depending on the complexity of the view and on its "cacheability".
You should also consider whether the content of that view can be changed by other users browsing the site at the same time that "our" user: should the view become populated after "our" user has loaded the page, "our" user won't ever know.
As on how to achieve what you want, please see the accepted answer.
HTH!
I override views_embed_view() to only provide output if there is content, and then call my override from the theme layer:
function mymodule_embed_view($name, $display_id = 'default') {
// handle any add'l args (this hook supports optional params)
$args = func_get_args();
array_shift($args);
if (count($args)) {
array_shift($args);
}
$view = views_get_view($name);
$output = $view->preview($display,$args);
if ($view->result) {
return $output;
}
}
Then in the template file:
<?php
$view = mymodule_embed_view('view_name');
if (strlen($view) > 0) {
print $view;
}
?>

Resources