How do I rewrite the path in the wordpress account menu? - wordpress

I have the following code in the functions.php file.
add_action( 'init', 'add_admin_tools_account_endpoint' );
function add_admin_tools_account_endpoint() {
add_rewrite_endpoint( 'wp-admin', EP_PAGES );
}
add_filter ( 'woocommerce_account_menu_items', 'custom_account_menu_items', 10 );
function custom_account_menu_items( $menu_links ){
if ( current_user_can('administrator') ) {
$menu_links = array_slice( $menu_links, 0,0 , true )
+ array( 'wp-admin' => __('Admin tools') )
+ array_slice( $menu_links, 0, NULL, true );
}
return $menu_links;
}
add_action( 'woocommerce_account_admin-tools_endpoint', 'admin_tools_account_endpoint_content' );
function admin_tools_account_endpoint_content() {
if ( current_user_can('administrator') ) {
echo "<h3 class='headline'>Admin Tools</h3>
<p style='text-align:center;'>Test of various functions.</p>";
}
}
My problem is that it points to: https://{PATH}/my-account/wp-admin. I need to go to https://{PATH}/wp-admin instead.
Thanks in advanced

You should remove the endpoint from the my-account page using the remove_rewrite_endpoint function. Then, in the custom_account_menu_items function, we add a direct link to the wp-admin page using the admin_url function.
add_action( 'init', 'add_admin_tools_account_endpoint' );
function add_admin_tools_account_endpoint() {
// Remove the endpoint from the my-account page
remove_rewrite_endpoint( 'wp-admin', EP_PAGES );
}
add_filter ( 'woocommerce_account_menu_items', 'custom_account_menu_items', 10 );
function custom_account_menu_items( $menu_links ){
if ( current_user_can('administrator') ) {
// Add the link to the wp-admin page
$menu_links['wp-admin'] = __('Admin tools');
}
return $menu_links;
}
add_action( 'woocommerce_account_menu_items', 'admin_tools_account_menu_link' );
function admin_tools_account_menu_link( $menu_links ) {
if ( current_user_can('administrator') ) {
$menu_links['wp-admin'] = 'Admin tools';
}
return $menu_links;
}

Try this..
add_action( 'init', 'add_admin_tools_account_endpoint' );
function add_admin_tools_account_endpoint() {
add_rewrite_endpoint( 'wp-admin', EP_ROOT );
}
add_filter ( 'woocommerce_account_menu_items', 'custom_account_menu_items', 10 );
function custom_account_menu_items( $menu_links ){
if ( current_user_can('administrator') ) {
$menu_links = array_slice( $menu_links, 0,0 , true )
+ array( 'wp-admin' => __('Admin tools') )
+ array_slice( $menu_links, 0, NULL, true );
}
return $menu_links;
}
add_action( 'template_redirect', 'admin_tools_account_endpoint_redirect' );
function admin_tools_account_endpoint_redirect() {
global $wp_query;
if ( isset( $wp_query->query_vars['wp-admin'] ) ) {
wp_redirect( site_url( '/wp-admin/' ) );
exit;
}
}
add_action( 'woocommerce_account_wp-admin_endpoint', 'admin_tools_account_endpoint_content' );
function admin_tools_account_endpoint_content() {
if ( current_user_can('administrator') ) {
echo "<h3 class='headline'>Admin Tools</h3>
<p style='text-align:center;'>Test of various functions.</p>";
}
}
In the add_admin_tools_account_endpoint() function, we have changed the EP_PAGES argument to EP_ROOT. This sets the endpoint to the root URL instead of to the account page
I have added a new function admin_tools_account_endpoint_redirect() that redirects the endpoint to site_url( '/wp-admin/' ) if the wp-admin query var is present in the URL. This is necessary because we have changed the endpoint to the root URL, so we need to manually redirect it to the correct page
We have changed the action in the add_action() call for displaying the endpoint content to woocommerce_account_wp-admin_endpoint to match the new endpoint name.
With these changes, the URL for the "Admin tools" link in the account menu should point to https://{PATH}/wp-admin, as desired

Related

Setting Cookie for Custom URL Parameter - wordpress/woocommerce

I've created a shortcode that always me to use a URL parameter to dynamically swap the featured product on the home page which works well:
// Shortcode to display specific product page via URL - ?myppid=46
// =============================================================================
function ppid_from_query( $atts ) {
$atts = shortcode_atts( array(
'default' => 46
), $atts, 'myppid' );
$pp_id = $atts['default'];
if ( isset( $_REQUEST['ppid'] ) && $_REQUEST['ppid'] != '' ) {
$pp_id = intval( $_REQUEST['ppid'] );
}
return do_shortcode( "[product_page id='".$pp_id."']" );
}
add_shortcode( 'myppid', 'ppid_from_query' );
The challenge I'm having, is that if the user goes to any other page on my site and returns, the URL parameter is gone, and the default product shows up.
I've tried several methods for passing the parameter, but have not succeeded... Even if I had, it would have worked for that session only. In other words, if user leaves site and comes back to primary domain without ?ppid=X, then they won't see that product. So to that end, I've tried setting a cookie per this thread I found (granted it's a bit dated): https://wordpress.stackexchange.com/questions/188749/i-am-looking-to-append-url-parameter-to-all-urls
So in my header, I have:
<script>
if(!isset($_SESSION['ppid']) and $_GET['ppid']){
$cookie_expire = time()+60*60*24*30;
$_SESSION['ppid'] = $_GET['ppid'];
setcookie('ppid', $_SESSION['ppid'], $cookie_expire, '/', '.'.$_SERVER['HTTP_HOST']);
</script>
and in functions:
function wprdcv_param_redirect(){
if(isset($_COOKIE['ppid']) and !$_GET['ppid']){
$location = esc_url(add_query_arg('ppid', $_COOKIE['ppid']));
wp_redirect($location);
}
}
add_action('template_redirect', 'wprdcv_param_redirect');
Still no luck. What am I doing wrong?
The PHP code is processed by the web server and not by the browser. You don't have to set the cookie between the <script> tags. Instead, run it via the Wordpress init hook.
Based on #MattMelton's comment I added the checkout page exclusion in the wprdcv_param_redirect function.
You can optimize your functions like this:
add_shortcode( 'myppid', 'ppid_from_query' );
function ppid_from_query( $atts ) {
$atts = shortcode_atts( array(
'default' => 46
), $atts, 'myppid' );
$pp_id = $atts['default'];
if ( isset( $_REQUEST['ppid'] ) && $_REQUEST['ppid'] != '' ) {
$pp_id = intval( $_REQUEST['ppid'] );
}
return do_shortcode( "[product_page id='".$pp_id."']" );
}
// set the cookie based on the url parameter "ppid"
add_action( 'init', 'set_cookie_based_on_url_parameter_ppid' );
function set_cookie_based_on_url_parameter_ppid() {
if ( ! isset($_SESSION['ppid'] ) && $_GET['ppid'] ) {
$cookie_expire = time()+60*60*24*30;
$_SESSION['ppid'] = $_GET['ppid'];
setcookie('ppid', $_SESSION['ppid'], $cookie_expire, '/', '.'.$_SERVER['HTTP_HOST']);
}
}
add_action('template_redirect', 'wprdcv_param_redirect');
function wprdcv_param_redirect(){
// if it's the checkout page, don't redirect
if ( is_checkout() ) {
return;
}
/*
// if it is the order confirmation page in checkout, please do not redirect
if ( is_checkout() && is_wc_endpoint_url( 'order-received' ) ) {
return;
}
*/
if ( isset($_COOKIE['ppid']) && ! $_GET['ppid'] ) {
$location = esc_url( add_query_arg('ppid', $_COOKIE['ppid']) );
wp_redirect($location);
}
}
The code has been tested and works for me. Add it to your active theme's functions.php.

admin_enqueue_scripts not working in specific admin page

This is my code in functions.php file.
function my_enqueue($hook) {
if ( 'bookings' != $hook ) {
return;
}
wp_enqueue_style('datatablecss','//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css' );
wp_enqueue_style('datatablecss2','//cdn.datatables.net/1.10.16/css/dataTables.bootstrap.min.css' );
wp_enqueue_script('datatablejs','//cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js',array(),'1.0',false);
wp_enqueue_script('datatablejs2','//cdn.datatables.net/1.10.16/js/dataTables.bootstrap.min.js',array(),'1.0',false);}add_action( 'admin_enqueue_scripts', 'my_enqueue' );
My custom page name is bookings
and url is https://hireo.co.uk/wp-admin/admin.php?page=bookings
Any Solution for this?
Try this
if(isset($_GET['page']) && $_GET['page'] == 'options'){
wp_enqueue_style( 'akbank-bootstrap-min-css', 'https://cdn.jsdelivr.net/npm/bootstrap#3.3.7/dist/css/bootstrap.min.css');
wp_enqueue_style( 'akbank-bootstrap-theme-css', 'https://cdn.jsdelivr.net/npm/bootstrap#3.3.7/dist/css/bootstrap-theme.min.css');
wp_enqueue_script( 'akbank-bootstrap-min-js', 'https://cdn.jsdelivr.net/npm/bootstrap#3.3.7/dist/js/bootstrap.min.js');
}
if condition set is_admin()
function my_enqueue($hook) {
if ( 'bookings' != $hook ) {
return;
}
if ( is_admin() ) {
wp_enqueue_style('datatablecss','//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css' );
wp_enqueue_style('datatablecss2','//cdn.datatables.net/1.10.16/css/dataTables.bootstrap.min.css' );
wp_enqueue_script('datatablejs','//cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js',array(),'1.0',false);
wp_enqueue_script('datatablejs2','//cdn.datatables.net/1.10.16/js/dataTables.bootstrap.min.js',array(),'1.0',false);}
add_action( 'wp_enqueue_scripts', 'my_enqueue' );
}

get_query_var don't working although it's in $wp->query_vars

I try to use get_query_var for a new parameter "forumid".
I see the parameter when I print ($wp->query_vars),
Array (
[forumid] => 23 )
But the get_query_var("forumid") return NULL
add_filter( 'query_vars', 'wpse9870_query_vars' );
function wpse9870_query_vars( $query_vars )
{
$query_vars[] = 'forumid';
return $query_vars;
}
add_action( 'parse_request', 'wpse9870_parse_request' );
function wpse9870_parse_request( &$wp )
{
if ( array_key_exists( 'forumid', $wp->query_vars ) ) {
echo get_query_var('forumid');
require 'wp-content/plugins/forum/2.php';
exit();
}
return;
}
In the file wp-content/plugins/forum/2.php I also get Null for get_query_var('forumid')
The action hook parse_request is to early.
Read here -> Action_Reference
The hook parse_request run's before parse_query where the query variables are just ben setted.
I think you should use parse_query instead of parse_request.
add_action( 'parse_query', 'wpse9870_parse_request' );
function wpse9870_parse_request( &$wp )
{
if ( array_key_exists( 'forumid', $wp->query_vars ) ) {
echo get_query_var('forumid');
require 'wp-content/plugins/forum/2.php';
exit();
}
return;
}

Add input field to every item in cart

I am trying to add a new field on my cart.php file.
I actually want to insert a URL field, so user can set a URL for each order item.
I tried to use a code from another post here but I can't get it to work.
The first and the second functions are working but when it comes to the third one, 'woocommerce_get_item_data' the $cart_item['url'] doesn't contain anything even if I add something in the field and I press Update Cart.
$cart_totals[ $cart_item_key ]['url'] from the first function is outputting the right value when the page load.
I don't know what to do now, thanks for any help.
Here is the code
Add the field
cart/cart.php
<td class="product-url">
<?php
$html = sprintf( '<div class="url"><input type="text" name="cart[%s][url]" value="%s" size="4" title="Url" class="input-text url text" /></div>', $cart_item_key, esc_attr( $values['url'] ) );
echo $html;
?>
</td>
functions.php
// get from session your URL variable and add it to item
add_filter('woocommerce_get_cart_item_from_session', 'cart_item_from_session', 99, 3);
function cart_item_from_session( $data, $values, $key ) {
$data['url'] = isset( $values['url'] ) ? $values['url'] : '';
return $data;
}
// this one does the same as woocommerce_update_cart_action() in plugins\woocommerce\woocommerce-functions.php
// but with your URL variable
// this might not be the best way but it works
add_action( 'init', 'update_cart_action', 9);
function update_cart_action() {
global $woocommerce;
if ( ( ! empty( $_POST['update_cart'] ) || ! empty( $_POST['proceed'] ) ) ) {
$cart_totals = isset( $_POST['cart'] ) ? $_POST['cart'] : '';
if ( sizeof( $woocommerce->cart->get_cart() ) > 0 ) {
foreach ( $woocommerce->cart->get_cart() as $cart_item_key => $values ) {
if ( isset( $cart_totals[ $cart_item_key ]['url'] ) ) {
$woocommerce->cart->cart_contents[ $cart_item_key ]['url'] = $cart_totals[ $cart_item_key ]['url'];
}
}
}
}
}
// this is in Order summary. It show Url variable under product name. Same place where Variations are shown.
add_filter( 'woocommerce_get_item_data', 'item_data', 10, 2 );
function item_data( $data, $cart_item ) {
if ( isset( $cart_item['url'] ) ) {
$data['url'] = array('name' => 'Url', 'value' => $cart_item['url']);
}
return $data;
}
// this adds Url as meta in Order for item
add_action ('woocommerce_add_order_item_meta', 'add_item_meta', 10, 2);
function add_item_meta( $item_id, $values ) {
woocommerce_add_order_item_meta( $item_id, 'Url', $values['url'] );
}
Add a textarea field to a WooCommerce cart item
First, we just need to add the textarea field. We use the woocommerce_after_cart_item_name hook so our textarea will appear after the product name.
<?php
/**
* Add a text field to each cart item
*/
function prefix_after_cart_item_name( $cart_item, $cart_item_key ) {
$notes = isset( $cart_item['notes'] ) ? $cart_item['notes'] : '';
printf(
'<div><textarea class="%s" id="cart_notes_%s" data-cart-id="%s">%s</textarea></div>',
'prefix-cart-notes',
$cart_item_key,
$cart_item_key,
$notes
);
}
add_action( 'woocommerce_after_cart_item_name', 'prefix_after_cart_item_name', 10, 2 );
/**
* Enqueue our JS file
*/
function prefix_enqueue_scripts() {
wp_register_script( 'prefix-script', trailingslashit( plugin_dir_url( __FILE__ ) ) . 'update-cart-item-ajax.js', array( 'jquery-blockui' ), time(), true );
wp_localize_script(
'prefix-script',
'prefix_vars',
array(
'ajaxurl' => admin_url( 'admin-ajax.php' )
)
);
wp_enqueue_script( 'prefix-script' );
}
add_action( 'wp_enqueue_scripts', 'prefix_enqueue_scripts' );
´´´
At the moment, the user will be able to enter text into the field but the text won’t save. We are going to use some AJAX to save the text.
The code above not only adds the textarea to the cart item, it also enqueues a JavaScript file ready for our AJAX.
It’s assumed that you’re using the code on this page to create a new plugin. If so, you should create a new JS file with the code below and place the file in the root directory of your plugin.
However, if you’ve added the PHP above to your theme functions.php or as a snippet on your site, you’ll need to change the location of the JS file by updating line 21 of the snippet above to identify the location of the JS file.
´´´
(function($){
$(document).ready(function(){
$('.prefix-cart-notes').on('change keyup paste',function(){
$('.cart_totals').block({
message: null,
overlayCSS: {
background: '#fff',
opacity: 0.6
}
});
var cart_id = $(this).data('cart-id');
$.ajax(
{
type: 'POST',
url: prefix_vars.ajaxurl,
data: {
action: 'prefix_update_cart_notes',
security: $('#woocommerce-cart-nonce').val(),
notes: $('#cart_notes_' + cart_id).val(),
cart_id: cart_id
},
success: function( response ) {
$('.cart_totals').unblock();
}
}
)
});
});
})(jQuery);
´´´
Now, when the user types anything, the contents of the text field get sent back to the server ready to be saved as meta data to the cart item.
´´´
<?php
/**
* Update cart item notes
*/
function prefix_update_cart_notes() {
// Do a nonce check
if( ! isset( $_POST['security'] ) || ! wp_verify_nonce( $_POST['security'], 'woocommerce-cart' ) ) {
wp_send_json( array( 'nonce_fail' => 1 ) );
exit;
}
// Save the notes to the cart meta
$cart = WC()->cart->cart_contents;
$cart_id = $_POST['cart_id'];
$notes = $_POST['notes'];
$cart_item = $cart[$cart_id];
$cart_item['notes'] = $notes;
WC()->cart->cart_contents[$cart_id] = $cart_item;
WC()->cart->set_session();
wp_send_json( array( 'success' => 1 ) );
exit;
}
add_action( 'wp_ajax_prefix_update_cart_notes', 'prefix_update_cart_notes' );
function prefix_checkout_create_order_line_item( $item, $cart_item_key, $values, $order ) {
foreach( $item as $cart_item_key=>$cart_item ) {
if( isset( $cart_item['notes'] ) ) {
$item->add_meta_data( 'notes', $cart_item['notes'], true );
}
}
}
add_action( 'woocommerce_checkout_create_order_line_item', 'prefix_checkout_create_order_line_item', 10, 4 );
´´´
The prefix_update_cart_notes function does a security check using the WooCommerce cart nonce then saves the content of the textarea as meta data in the cart item. You can check out this article for more information about updating cart meta for items that have already been added to the cart.
Add the custom text to the order meta
Finally, we want to pass our meta data to the order so that we can use it after the customer has checked out. The prefix_checkout_create_order_line_item function takes care of that, iterating through each item and saving notes when it finds them.
https://pluginrepublic.com/how-to-add-an-input-field-to-woocommerce-cart-items/

Remove action 'woocommerce_email_before_order_table' not working

I am trying to remove the "Our bank information" and payment instructions from Woocommerce BACS gateway thankyou page and emails.
I know it should be done simply by removing the woocommerce_thankyou_bacs and woocommerce_email_before_order_table action.
I managed to remove the message from thankyou page, but it still appears in the emails. I checked, woocommerce_thankyou_bacs and woocommerce_email_before_order_table are both removed from wp_filter global.
I am relying on a function i copied from here: http://wpquestions.com/question/showChrono/id/9204 due to having similar problem of remove_action not working due to different unique id, and it works, in a way that the actions are gone from wp_filter global.
I have tried all kind of priorities, 0-20, the thankyou page message is gone but email still shows the payment instructions.
My code is as follows:
add_action( 'woocommerce_thankyou_bacs', function() {
if( function_exists( 'wc_gateway_remove_hook' ) ) {
//Remove BACS payment instructions from thankyou page <- WORKS!
wc_gateway_remove_hook( 'WC_Gateway_BACS', 'woocommerce_thankyou_bacs', 'thankyou_page' );
//Remove BACS payment instructions from email <- DOESN'T WORK!
wc_gateway_remove_hook( 'WC_Gateway_BACS', 'woocommerce_email_before_order_table', 'email_instructions' );
}
}, 10 );
function wc_gateway_remove_hook( $classname, $hook, $callback ) {
foreach( (array) $GLOBALS['woocommerce']->payment_gateways->payment_gateways as $key => $gateway_obj ) {
if( $classname === get_class( $gateway_obj ) ) {
remove_action( $hook, array( $gateway_obj, $callback ) );
}
}
}
Try this:
add_action( 'woocommerce_email_before_order_table', function() {
if( function_exists( 'wc_gateway_remove_hook' ) ) {
wc_gateway_remove_hook( 'WC_Gateway_BACS', 'woocommerce_email_before_order_table', 'email_instructions' );
}
}, 10);
function wc_gateway_remove_hook( $classname, $hook, $callback ) {
foreach( (array) $GLOBALS['woocommerce']->payment_gateways->payment_gateways as $key => $gateway_obj ) {
if( $classname === get_class( $gateway_obj ) ) {
remove_action( $hook, array( $gateway_obj, $callback ) );
}
}
}

Resources