Skip to content

Instantly share code, notes, and snippets.

@ScottJWalter
Forked from claudiosanches/custom-my-account-endpoint.php
Last active November 9, 2018 13:13
Show Gist options
  • Save ScottJWalter/d2e7d3b25b28a18886bdf5fd090748c4 to your computer and use it in GitHub Desktop.
Save ScottJWalter/d2e7d3b25b28a18886bdf5fd090748c4 to your computer and use it in GitHub Desktop.
PHP Class that wraps creating custom "My Account" endpoints inside WooCommerce
<?php
defined( 'ABSPATH' ) or exit;
class CUSTOM_WC_My_Account_Endpoint {
/**
* Properties
*
* @prop string $endpoint URI slug of endpoint
* @prop string $title Text to display on menu
* @prop callback $callback Display/Draw function to call
* @prop callback $menu_items Override the new menu attribute method
*/
public $endpoint;
public $title;
public $callback;
public $menu_items;
/**
* Constructor
*
* @param string $endpoint URI slug of endpoint
* @param string $title Text to display on menu
* @param callback $callback Optional. Display/Draw function to call
* @param callback $menu_items Optional. Override new_menu_items method
*/
public function __construct( $endpoint, $title, $callback = null, $menu_items = null ) {
// Grab the parameters for the life of this object
$this->endpoint = $endpoint;
$this->title = $title;
$this->callback = $callback;
$this->menu_items = $menu_items;
// Insert a new endpoint into WordPress.
add_action( 'init', array( $this, 'add_endpoints' ) );
add_filter( 'query_vars', array( $this, 'add_query_vars' ), 0 );
// Change the My Accout page title.
add_filter( 'the_title', array( $this, 'endpoint_title' ) );
// Insert new tab/page into the My Account page.
add_filter( 'woocommerce_account_menu_items', array( $this, 'new_menu_items' ) );
add_action( 'woocommerce_account_' . $this->endpoint . '_endpoint', array( $this, 'endpoint_content' ) );
}
/**
* Register new endpoint to use inside My Account page.
*
* @see https://developer.wordpress.org/reference/functions/add_rewrite_endpoint/
*/
public function add_endpoints() {
add_rewrite_endpoint( $this->endpoint, EP_ROOT | EP_PAGES );
}
/**
* Add new query var.
*
* @param array $vars
* @return array
*/
public function add_query_vars( $vars ) {
$vars[] = $this->endpoint;
return $vars;
}
/**
* Set endpoint title.
*
* @param string $title
* @return string
*/
public function endpoint_title( $title ) {
global $wp_query;
$is_endpoint = isset( $wp_query->query_vars[ $this->endpoint ] );
if ( $is_endpoint && ! is_admin() && is_main_query() && in_the_loop() && is_account_page() ) {
// New page title.
$title = __( $this->title, 'woocommerce' );
remove_filter( 'the_title', array( $this, 'endpoint_title' ) );
}
return $title;
}
/**
* Insert the new endpoint into the My Account menu.
*
* If this function isn't overridden during construction, it will
* (by default) place the new menu item at the bottom of the My Account
* menu, just above 'Customer Logout'.
*
* @param array $items
* @return array
*/
public function new_menu_items( $items ) {
if ( $this->menu_items ) {
return call_user_func( $this->menu_items, $items );
} else {
// Remove the logout menu item.
$logout = $items['customer-logout'];
unset( $items['customer-logout'] );
// Insert your custom endpoint.
$items[ $this->endpoint ] = __( $this->title, 'woocommerce' );
// Insert back the logout item.
$items['customer-logout'] = $logout;
return $items;
}
}
/**
* Endpoint HTML content.
*/
public function endpoint_content() {
if ( $this->callback ) {
call_user_func( $this->callback );
} else {
echo '<p>You need to override this with your own callback!</p>';
}
}
/**
* Plugin install action.
* Flush rewrite rules to make our custom endpoint available.
*/
public static function install() {
flush_rewrite_rules();
}
}
@ScottJWalter
Copy link
Author

ScottJWalter commented Nov 9, 2018

This is a refactoring of the forked script making the class self-contained (no hardcoded values), allowing you to use this class multiple times to create more than one My Account endpoint easily.

Usage:

require_once 'class.endpoint.php'

function CUSTOM_my_endpoint_draw() {
    // create and display the content of your endpoint
    $html = "<p>Your content here</p>";

    // ...

    echo $html;  // Note:  This function should 'echo' the final output
}

function CUSTOM_my_endpoint_menu( $items ) {
    // Re-arrange the My Account menu items

    // ...

    return $items;  // Note:  This function returns the array of menu items
}

$my_new_endpoint = new CUSTOM_WC_My_Account_Endpoint(
    'my-endpoint',  # https://.../my-account/my-endpoint/...
    'My Endpoint',  # Text displayed in My Account menu
    'CUSTOM_my_endpoint_draw',  # name of drawing function
    'CUSTOM_my_endpoint_menu'  # name of menu function
);

// Register the plugin (can't be done from inside the class)
register_activation_hook( __FILE__, array( $my_new_endpoint, 'install' ) );

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment