I am using WooCommerce subscriptions and am trying to create a custom flow in the dhasboard for the user.
Currently user logs in > dashboard shows, I have custom code to show if subscription status is "active" or "on-hold". If it is on hold, the user currently has to click on view subscription, then click on a listed subscription and then click renew in the actions section.
I want to move this actions button to renew an "on-hold" subscription out of the subscription-details.php file and into the dashboard.php file to reduce these steps.
Here is the snippet i've found that I think relates to the renew action button:
<?php do_action( 'woocommerce_subscription_before_actions', $subscription ); ?>
<?php $actions = wcs_get_all_user_actions_for_subscription( $subscription, get_current_user_id() ); ?>
<?php if ( ! empty( $actions ) ) : ?>
<tr>
<td><?php esc_html_e( 'Actions', 'woocommerce-subscriptions' ); ?></td>
<td>
<?php foreach ( $actions as $key => $action ) : ?>
<?php echo esc_html( $action['name'] ); ?>
<?php endforeach; ?>
</td>
</tr>
<?php endif; ?>
<?php do_action( 'woocommerce_subscription_after_actions', $subscription ); ?>
I tried to bring this into the dashboard.php file, however I get an error saying the site is experiencing technical difficulties.
Any ideas on how I could bring this renewal action button into the dashboard.php file instead?
Thanks in advance for any help!!!
If you want to show any of action in your custom page or dashboard then use below code and set action according to your requirements
function addCancelButton($subscription) {
$actions = wcs_get_all_user_actions_for_subscription( $subscription, get_current_user_id() );
if(!empty($actions)){
foreach ( $actions as $key => $action ){
if(strtolower($action['name']) == "cancel"){
$cancelLink = esc_url( $action['url'] );
echo "<a href='$cancelLink' class='button cancel'>".$action['name']."</a>";
}
}
}
}
add_action( 'woocommerce_my_subscriptions_actions', 'addCancelButton', 10 );
If you want to edit My account page then i suggest to use this hook in your child theme
woocommerce_account_dashboard
Here is code for same
add_action( 'woocommerce_account_dashboard','add_account_content_kiki' );
function add_account_content_kiki() {
if( has_active_subscription() ){ // Current user has an active subscription
echo '<div class="woocommerce-message woocommerce-message--info woocommerce-Message woocommerce-Message--info woocommerce-info"><a class="woocommerce-Button button" href="www.google.com">Test Now</a>Test link - shop now</div>';
// Example of displaying something
echo 'You have active subscription';
}
}
you have to add this function also in function file
function has_active_subscription( $user_id='' ) {
// When a $user_id is not specified, get the current user Id
if( '' == $user_id && is_user_logged_in() )
$user_id = get_current_user_id();
// User not logged in we return false
if( $user_id == 0 )
return false;
return wcs_user_has_subscription( $user_id, '', 'active' );
}
Reference of hook - https://docs.woocommerce.com/wc-apidocs/hook-docs.html
All hook you can use from here for woo commerce my account page - https://businessbloomer.com/woocommerce-visual-hook-guide-account-pages/
Related
By default the store only accepts credit card but I need to allow some pre-approved customers to have the ability to pay by check.
I got this working with a custom user role and the following code:
add_filter( 'woocommerce_available_payment_gateways', 'allow_to_pay_by_check' );
function allow_to_pay_by_check( $available_gateways ) {
if ( isset( $available_gateways['cheque'] ) && ! current_user_can('pay_using_cheque') ) {
unset( $available_gateways['cheque'] );
}
return $available_gateways;
}
It works and gives them the ability to pay by check AND credit cards. The issue is that I don't think this should be a user role. It should be located under each customer (Users) account details as a check box to turn on or off. Is this possible?
The following will add to admin users pages a custom checkbox field that will enable or disable "Cheque" payment method:
// Add allowed custom user field in admin
add_action( 'show_user_profile', 'add_customer_checkbox_field', 10 );
add_action( 'edit_user_profile', 'add_customer_checkbox_field', 10 );
function add_customer_checkbox_field( $user )
{
?>
<h3><?php _e("Payment option"); ?></h3>
<table class="form-table">
<tr>
<th><?php _e("Pay by Cheque"); ?></th>
<td>
<?php
woocommerce_form_field( 'pay_by_cheque', array(
'type' => 'checkbox',
'class' => array('input-checkbox'),
'label' => __('Allowed'),
), get_user_meta( $user->id, 'pay_by_cheque', true ) );
?>
</td>
</tr>
</table>
<?php
}
// Save allowed custom user field in admin
add_action( 'personal_options_update', 'save_customer_checkbox_field' );
add_action( 'edit_user_profile_update', 'save_customer_checkbox_field' );
function save_customer_checkbox_field( $user_id )
{
if ( current_user_can( 'edit_user', $user_id ) ) {
update_user_meta( $user_id, 'pay_by_cheque', isset($_POST['pay_by_cheque']) ? '1' : '0' );
}
}
// Enabling or disabling "Cheque" payment method
add_filter( 'woocommerce_available_payment_gateways', 'allow_to_pay_by_cheque' );
function allow_to_pay_by_cheque( $available_gateways ) {
if ( isset( $available_gateways['cheque'] ) && ! get_user_meta( get_current_user_id(), 'pay_by_cheque', true ) ) {
unset( $available_gateways['cheque'] );
}
return $available_gateways;
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
I'm trying to create a tabbed version of "My Account" in woocommerce.
I have built my pages in php using bootstrap css and included the wordpress header and footer so the page loads correctly.
The tabs display as expected by I am having an issue with the endpoint urls in woocommerce:
- 'edit-address'
- 'view-order'
These endpoints are generated dynamically and appended to the url: www.site-name.com/my-account/edit-address
Here's the function call (in file .plugins/woocommerce/myaccount/form-edit-address.php):
<a href="<?php echo wc_get_endpoint_url( 'edit-address', $name ); ?>
I've included 'my-addresses' in my tabbed page which dispays ok. However, the link to edit the shipping and billing addresses is generated by the above call to the endpoints. When the link is clicked the page fails to load and returns a 404 error.
My custom php page is basically www.site-name.com/account/edit-address
The problem is:
The 'edit-address' page content is not loading and I get a 404 error
I'm guessing the issue is caused because my pages are external php pages and not stored with wp database?
Is there a way I can customise the endpoint url so it appends correctly and loads the page?
Link to the page on my site: www.thecookerytutor dot co dot uk/account
Origional woocommerce my-account page: www.thecookerytutor dot co dot uk/my-account
(You will need to create a login to view both pages)
It's had me stumped for days!
Thanks in advance.
Code for my addresses tab on my custom php page as promised...
echo "<div id = 'edit-addresses' class='tab-pane fade'>";
echo "<div id = 'content' class = 'page col-full'>";
echo "<section id = 'main' class = 'col-left'>";
echo "<BR>";
include "my-address.php";
echo "</section>";
echo "</div>";
echo "</div>";`
As you can see I'm including the wc page that loads the addresses (I've copied to the local folder)
Here's the content of edit-address.php (I've copied to my local folder and added wp header). The page loads the header but the get address function fails at line 50.
<?php
define('WP_USE_THEMES', false);
require('../wp-blog-header.php');
add_filter( 'wp_title', 'wp_title_so_18381106', 10, 3 );
function wp_title_so_18381106( $title, $sep, $seplocation )
{
return 'Your Account | ';
}
get_header();
?>
<?php
/**
* Edit address form
*
* #author WooThemes
* #package WooCommerce/Templates
* #version 2.1.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
global $current_user;
$page_title = ( $load_address === 'billing' ) ? __( 'Billing Address', 'woocommerce' ) : __( 'Shipping Address', 'woocommerce' );
get_currentuserinfo();
?>
<?php wc_print_notices(); ?>
<?php //if ( ! $load_address ) : ?>
<?php //wc_get_template( 'myaccount/my-address.php' ); ?>
<?php //else : ?>
<form method="post">
<h3><?php echo apply_filters( 'woocommerce_my_account_edit_address_title', $page_title ); ?></h3>
<?php do_action( "woocommerce_before_edit_address_form_{$load_address}" ); ?>
/fails to load here/
<?php foreach ( $address as $key => $field ) : ?>
<?php woocommerce_form_field( $key, $field, ! empty( $_POST[ $key ] ) ? wc_clean( $_POST[ $key ] ) : $field['value'] ); ?>
<?php endforeach; ?>
<?php do_action( "woocommerce_after_edit_address_form_{$load_address}" ); ?>
<p>
<input type="submit" class="button" name="save_address" value="<?php _e( 'Save Address', 'woocommerce' ); ?>" />
<?php wp_nonce_field( 'woocommerce-edit_address' ); ?>
<input type="hidden" name="action" value="edit_address" />
</p>
</form>
<?php //endif; ?>
WooCommerce is a plugin for WordPress, you can't use it without WordPress... for example /my-account/edit-address/, that my-account is actually the page you are rendering and edit-address is just a variable. edit-address was added as an endpoint to my-account. you need to do the same for your account.
You should get an idea of what endpoints are.
Other thoughts about this. If you really want to use account and not my-account, look into your pages for "My Account" and change it's permalink. You can also create another page that can use account in it's permalink. Then use that page in your WooCommerce > Settings > Account tab > My Account Page.
If you have some custom php codes, you can just copy the template from your woocommerce plugin to your theme folder and edit the file you need. Read Template Structure + Overriding Templates via a Theme.
And if I have not addressed your problem, comment down below.
In WooCommerce, I want to redirect the cart page to shop page when the cart page is empty otherwise shows the cart page. Can anyone have the solution ?
Here is the code I have tried, but it does not work:
function my_empty_cart() {
global $woocommerce;
if (isset( $_GET['empty-cart'] ) ) {
wp_safe_redirect( get_permalink( woocommerce_get_page_id( 'product' ) ) );
}
}
add_action( 'init', 'my_empty_cart' );
// old woocommerce : use sizeof( $woocommerce->cart->cart_contents) to check cart content count
// In new woocommerce 2.1+ : WC()->cart->cart_contents_count to check cart content count
add_action("template_redirect", 'redirection_function');
function redirection_function(){
global $woocommerce;
if( is_cart() && WC()->cart->cart_contents_count == 0){
wp_safe_redirect( get_permalink( woocommerce_get_page_id( 'shop' ) ) );
}
}
init hook will run everytime. use template_redirect
==============Updates=============
In new woocommerce, they have updated the functionality and now you can use following function to directly get the cart content count.
WC()->cart->cart_contents_count
2021 Update
Since WooCommerce version 3 use the following to redirect to shop page when trying to access cart page and cart is already empty:
add_action( 'template_redirect', 'empty_cart_redirect' );
function empty_cart_redirect(){
if( is_cart() && WC()->cart->is_empty() ) {
wp_safe_redirect( get_permalink( wc_get_page_id( 'shop' ) ) );
exit();
}
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
Notes - Obsolete and deprecated code:
global $woocommerce; use with $woocommerce->cart is replaced simply by WC()->cart
sizeof($woocommerce->cart->cart_contents) == 0 is replaced by simple WC()->cart->is_empty()
woocommerce_get_page_id() is replaced by wc_get_page_id()
When removing all cart items on cart page, to make the redirection active, some additional jQuery code is required, see: Redirect to shop if cart is emptied on cart page in WooCommerce 3+
Just tested this myself as I needed something similar.
function cart_empty_redirect_to_shop() {
global $woocommerce;
if ( is_page('cart') and !sizeof($woocommerce->cart->cart_contents) ) {
wp_redirect( get_permalink( wc_get_page_id( 'shop' ) ) ); exit;
}
}
add_action( 'wp_head', 'cart_empty_redirect_to_shop' );
I tried #Pushpak's solution, but it doesn't work anymore. To check the cart content please use this code:
global $woocommerce;
if ( $woocommerce->cart->cart_contents_count != 0 ) {
// cart has content
} else {
// cart is empty
}
2018 - 25 - Sept
working for me today::
function cart_empty_redirect_to_shop() {
global $woocommerce, $woocommerce_errors;
if ( is_cart() && sizeof($woocommerce->cart->cart_contents) == 0) {
wp_safe_redirect( get_permalink( wc_get_page_id( 'shop' ) ) );
exit;
}
}
add_action( 'template_redirect', 'cart_empty_redirect_to_shop' );
Simply go to woocommerce folder and navigate to the CART folder.. in there is a cart-empty.php
then locate the following:
<p><a class="button1 btn btn-normal" href="<?php echo get_permalink.....
it would say getpermalink(woocommerce_.....
simply change that to
<p><a class="button1 btn btn-normal" href="<?php echo get_permalink('THE PAGE ID YOU WANT TO REDIRECT TO');
and bobs your uncle.. it will redirect to page with id you specify.
Let me know if you dont understand.
Using user meta data, I am running a function that is hidden in a user’s profile that allows them to have a checklist. I’m using Theme My Login and not including the checklist on the user’s profile page when they edit/view their profile.
I am trying to display the checklist on it’s own page. I can get it to display but can’t seem to get the Submit button to work. Can someone point me in the right direction?
Thanks!
Code example in functions.php:
function my_show_extra_profile_fields( $user ) { ?>
<div><input type="checkbox" name="checkbox1" id=" checkbox1 " value="yes" <?php if (esc_attr( get_the_author_meta( "checkbox1", $user->ID )) == "yes") echo "checked"; ?> />
Checkbox 1
</div>
<button type="submit">Save</button>
<?php }
?>
<?php
add_action( 'personal_options_update', 'my_save_extra_profile_fields' );
add_action( 'edit_user_profile_update', 'my_save_extra_profile_fields' );
function my_save_extra_profile_fields( $user_id ) {
if ( !current_user_can( 'edit_user', $user_id ) )
return false;
update_usermeta( $user_id, checkbox1, $_POST['checkbox1'] );
}
?>
Code example to display the extra profile field on my page template:
<?php my_show_extra_profile_fields(); ?>
EDIT: Forgot my '', added them back in
You have $_POST[checkbox1] it should be $_POST['checkbox1']
Assuming you created the field already, you can use wp_update_user from the codex.
$user_id = wp_update_user( array( 'ID' => $user_id, 'checkbox1' => $_POST['checkbox1'] ) );
if ( is_wp_error( $user_id ) ) {
// There was an error, probably that user doesn't exist.
} else {
// Success!
}
In Wordpress, I added some fields in the users dashboard. I made them required but I'd like to display a message if they are empty.
Here is an example (just one field) of what I did :
function my_admin_notice() { ?>
<div class="error">
<p><?php _e( 'Error!', 'user_street' ); ?></p>
</div>
<?php
}
function save_extra_user_profile_fields( $user_id ) {
if ( !current_user_can( 'edit_user', $user_id ) ) {
return false;
}
if (!empty($_POST['user_street'])) {
update_user_meta( $user_id, 'user_street', $_POST['user_street'] );
}
else {
add_action('admin_notices', 'my_admin_notice');
return false;
}
}
add_action( 'personal_options_update', 'save_extra_user_profile_fields' );
add_action( 'edit_user_profile_update', 'save_extra_user_profile_fields' );
Unfortunately, nothing happens.
I also tried with add_settings_error but I had the same problem.
Can someone give me a hand or just explain to me what I am doing wrong? It would be much appreciated! Thank you very much!
Looks like it's too late to add the admin_notice. An alternative is to use the action hook load-$page (that runs at the very beginning of a page load) and check if the user meta is empty. If so, trigger the notice.
add_action( 'load-profile.php', 'notice_so_23373245' );
add_action( 'load-user-edit.php', 'notice_so_23373245' );
function notice_so_23373245()
{
// Check to see if page is user-edit or profile
$user = isset( $_GET['user_id'] ) ? $_GET['user_id'] : get_current_user_id();
if( empty( get_user_meta( $user, 'user_street' ) ) )
add_action('admin_notices', 'my_admin_notice');
}