page_slug_prefix = $page_slug_prefix;
$this->file_version = defined('WP_DEBUG') && WP_DEBUG ? time() : BETTER_PAYMENT_VERSION;
$this->pro_enabled = apply_filters('better_payment/pro_enabled', false);
add_action('init', [$this, 'handle_old_page_redirect']);
add_action('admin_menu', [$this, 'register_menu']);
add_action('admin_enqueue_scripts', [$this, 'enqueue_admin_assets']);
add_action('admin_enqueue_scripts', [$this, 'customize_admin_footer']);
//EL Editor Style
add_action('elementor/editor/before_enqueue_scripts', [$this, 'editor_enqueue_scripts']);
}
/**
* Handle old page redirect
*
* @since 2.0.0
*/
public function handle_old_page_redirect()
{
if (isset($_GET['page']) && trim(sanitize_text_field($_GET['page'])) === 'better-payment-settings') {
wp_safe_redirect(admin_url('admin.php?page=' . $this->page_slug_prefix . '-admin&tab=dashboard'));
exit;
}
}
/**
* Enqueue editor scripts
*
* @since 0.0.1
*/
public function editor_enqueue_scripts()
{
// bp icon font
wp_enqueue_style(
'bp-icon-admin-editor',
BETTER_PAYMENT_ASSETS . '/icon/style.min.css',
false
);
}
/**
* Register admin menu for React SPA
*
* @since 1.5.0
*/
public function register_menu()
{
add_menu_page(
__('Better Payment', 'better-payment'),
__('Better Payment', 'better-payment'),
'manage_options',
$this->page_slug_prefix . '-admin',
[$this, 'render_react_admin_page'],
BETTER_PAYMENT_ASSETS . '/img/better-payment-icon-white-small.png',
64
);
$submenu_page_list = apply_filters('better_payment/admin/get_submenu_page_list', array(
$this->page_slug_prefix . '-admin&tab=dashboard' => array(
'title' => __('Dashboard', 'better-payment'),
'capability' => 'manage_options',
'callback' => [$this, 'render_react_admin_page'],
),
$this->page_slug_prefix . '-admin&tab=campaigns' => array(
'title' => __('Campaigns', 'better-payment'),
'capability' => 'manage_options',
'callback' => [$this, 'render_react_admin_page'],
),
$this->page_slug_prefix . '-admin&tab=transactions' => array(
'title' => __('Transactions', 'better-payment'),
'capability' => 'manage_options',
'callback' => [$this, 'render_react_admin_page'],
),
$this->page_slug_prefix . '-admin&tab=analytics' => array(
'title' => __('Analytics', 'better-payment'),
'capability' => 'manage_options',
'callback' => [$this, 'render_react_admin_page'],
),
$this->page_slug_prefix . '-admin&tab=settings' => array(
'title' => __('Settings', 'better-payment'),
'capability' => 'manage_options',
'callback' => [$this, 'render_react_admin_page'],
),
), $this->page_slug_prefix );
foreach( $submenu_page_list as $slug => $setting ) {
add_submenu_page(
$this->page_slug_prefix . '-admin',
$setting['title'],
$setting['title'],
$setting['capability'],
$slug,
$setting['callback']
);
}
remove_submenu_page($this->page_slug_prefix . '-admin', $this->page_slug_prefix . '-admin');
}
/**
* Render the React admin page
*
* @since 1.5.0
*/
public function render_react_admin_page()
{
$initial_data = $this->get_initial_admin_data();
add_filter('admin_body_class', function($classes) {
return $classes . ' better-payment-admin-page';
});
remove_all_actions('admin_notices');
remove_all_actions('all_admin_notices');
?>
rest_url('better-payment/v1/'),
'ajaxUrl' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('wp_rest'),
'importNonce' => wp_create_nonce('better_payment_transaction_import_nonce'),
'logoUrl' => BETTER_PAYMENT_ASSETS . '/img/better-payment-icon-white-small.png',
'adminUrl' => admin_url('admin.php?page=' . $this->page_slug_prefix . '-admin'),
'adminPostUrl' => admin_url('admin-post.php'),
'settings' => $settings,
'proEnabled' => $this->pro_enabled,
'currentUser' => [
'id' => get_current_user_id(),
'name' => wp_get_current_user()->display_name,
'email' => wp_get_current_user()->user_email
],
'currencies' => $this->get_currency_list(),
'currencySymbol' => $this->get_currency_symbol( $settings['better_payment_settings_general_general_currency'] ),
'campaignTemplates' => array_values( TemplateManager::get_all() ),
'adminBaseUrl' => admin_url(),
];
}
/**
* Customize admin footer text and version display
*
* @since 1.5.0
*/
public function customize_admin_footer($hook)
{
// Only apply to Better Payment admin pages — including the campaign
// builder page, whose hook is suffixed with 'bp-campaign-builder'
// rather than the '-admin' slug, so it shares the same branded footer.
if (
strpos($hook, $this->page_slug_prefix . '-admin') === false
&& strpos($hook, 'bp-campaign-builder') === false
) {
return;
}
add_filter('admin_footer_text', [$this, 'get_footer_text']);
add_filter('update_footer', [$this, 'get_footer_version']);
}
/**
* Get custom footer text
*
* @since 1.5.0
* @return string
*/
public function get_footer_text()
{
return __('Thank you for using Better Payment', 'better-payment');
}
/**
* Get footer version text
*
* @since 1.5.0
* @return string
*/
public function get_footer_version()
{
$free_version = BETTER_PAYMENT_VERSION;
// Check if Pro version is installed and active
if ($this->pro_enabled && defined('BETTER_PAYMENT_PRO_VERSION')) {
$pro_version = BETTER_PAYMENT_PRO_VERSION;
return sprintf(
__(' Pro Version ', 'better-payment'),
$free_version,
$pro_version
);
}
return sprintf(
__('Free Version ', 'better-payment'),
$free_version
);
}
/**
* Enqueue admin assets for React app
*
* @since 1.5.0
*/
public function enqueue_admin_assets($hook)
{
if (strpos($hook, $this->page_slug_prefix . '-admin') === false) {
return;
}
wp_enqueue_script('wp-element');
wp_enqueue_script('wp-api-fetch');
wp_enqueue_script('wp-components');
wp_enqueue_script('wp-i18n');
wp_enqueue_script('wp-element');
wp_enqueue_script('wp-hooks');
wp_enqueue_script('wp-i18n');
wp_enqueue_script('wp-api-fetch');
wp_enqueue_script('react');
wp_enqueue_script('react-dom');
$admin_js_file = BETTER_PAYMENT_ASSETS . '/admin/admin.min.js';
$admin_css_file = BETTER_PAYMENT_ASSETS . '/admin/admin.min.css';
if (!file_exists(BETTER_PAYMENT_PATH . '/assets/admin/admin.min.js')) {
$admin_js_file = BETTER_PAYMENT_ASSETS . '/admin/admin.js';
}
if (!file_exists(BETTER_PAYMENT_PATH . '/assets/admin/admin.min.css')) {
$admin_css_file = BETTER_PAYMENT_ASSETS . '/admin/admin.css';
}
wp_enqueue_script(
'better-payment-react-admin',
$admin_js_file,
['wp-element', 'wp-hooks', 'wp-i18n', 'wp-api-fetch', 'react', 'react-dom'],
$this->file_version,
true
);
wp_enqueue_style(
'better-payment-react-admin',
$admin_css_file,
[],
$this->file_version
);
// Campaign-list CSS contains the template-select modal styles needed on this page too.
$campaign_list_css = BETTER_PAYMENT_ASSETS . '/admin/campaign-list/campaign-list.min.css';
if ( file_exists( BETTER_PAYMENT_PATH . '/assets/admin/campaign-list/campaign-list.min.css' ) ) {
wp_enqueue_style(
'bp-campaign-list',
$campaign_list_css,
[],
$this->file_version
);
}
wp_add_inline_script(
'better-payment-react-admin',
'wp.apiFetch.use(wp.apiFetch.createNonceMiddleware("' . wp_create_nonce('wp_rest') . '"));',
'before'
);
$page_slug = $this->page_slug_prefix . '-admin';
$admin_base_url = admin_url('admin.php?page=' . $this->page_slug_prefix . '-admin');
$inline_spa_nav = "(function(){\n\n var PAGE_SLUG = '" . esc_js($page_slug) . "';\n var BASE_URL = '" . esc_url($admin_base_url) . "';\n\n function getTabFromUrl(){\n var params = new URLSearchParams(window.location.search);\n return params.get('tab') || 'dashboard';\n }\n\n function buildUrl(tab){\n var url = new URL(BASE_URL, window.location.origin);\n url.searchParams.set('tab', tab);\n return url.toString();\n }\n\n function setActiveSubmenu(tab){\n try {\n var top = document.getElementById('toplevel_page_'+PAGE_SLUG);\n if(!top) return;\n var submenu = top.querySelector('.wp-submenu');\n if(!submenu) return;\n // remove current from all\n submenu.querySelectorAll('li').forEach(function(li){ li.classList.remove('current'); });\n // match link by tab param\n var target = Array.prototype.find.call(submenu.querySelectorAll('a'), function(a){ return a.href && a.href.indexOf('page='+PAGE_SLUG) !== -1 && a.href.indexOf('tab='+tab) !== -1; });\n if(target && target.parentElement){ target.parentElement.classList.add('current'); }\n // ensure top-level marked as current submenu\n top.classList.add('wp-has-current-submenu');\n top.classList.add('current');\n } catch(e){}\n }\n\n // Global navigate helper used by WP menu interceptors and can be used by React too\n window.betterPaymentNavigate = function(tab, method){\n if(!tab){ tab = 'dashboard'; }\n var m = method === 'replace' ? 'replaceState' : 'pushState';\n var url = buildUrl(tab);\n try { window.history[m]({}, '', url); } catch(e){}\n setActiveSubmenu(tab);\n window.dispatchEvent(new CustomEvent('bp:navigate', { detail: { tab: tab } }));\n };\n\n // Intercept WP submenu clicks under our menu only\n function clickHandler(e){\n var link = e.target.closest('#toplevel_page_'+PAGE_SLUG+' .wp-submenu a');\n if(!link) return;\n var href = link.getAttribute('href') || '';\n if(href.indexOf('page='+PAGE_SLUG) === -1) return;\n e.preventDefault();\n var url = new URL(href, window.location.origin);\n var tab = url.searchParams.get('tab') || 'dashboard';\n window.betterPaymentNavigate(tab, 'push');\n }\n document.addEventListener('click', clickHandler, true);\n\n // Reflect browser back/forward\n window.addEventListener('popstate', function(){ setActiveSubmenu(getTabFromUrl()); });\n\n // Reflect initial state on load\n document.addEventListener('DOMContentLoaded', function(){ setActiveSubmenu(getTabFromUrl()); });\n\n // Also respond to React-driven page changes (optional hook)\n window.addEventListener('bp:page-changed', function(e){ if(e && e.detail && e.detail.tab){ setActiveSubmenu(e.detail.tab); } });\n\n})();";
wp_add_inline_script('better-payment-react-admin', $inline_spa_nav, 'after');
}
}