0
? ' ' . number_format_i18n( $counts['problems'] ) . ''
: '';
$dashboard_hook = add_menu_page(
__( '404Zen — Link Health', '404zen-broken-link-fixer' ),
__( '404Zen', '404zen-broken-link-fixer' ) . $badge,
self::CAPABILITY,
'lgbf-404zen',
array( __CLASS__, 'render_dashboard' ),
'dashicons-editor-unlink',
80
);
add_submenu_page(
'lgbf-404zen',
__( 'Dashboard', '404zen-broken-link-fixer' ),
__( 'Dashboard', '404zen-broken-link-fixer' ),
self::CAPABILITY,
'lgbf-404zen',
array( __CLASS__, 'render_dashboard' )
);
$settings_hook = add_submenu_page(
'lgbf-404zen',
__( '404Zen Settings', '404zen-broken-link-fixer' ),
__( 'Settings', '404zen-broken-link-fixer' ),
self::CAPABILITY,
'lgbf-404zen-settings',
array( __CLASS__, 'render_settings' )
);
$pricing_hook = add_submenu_page(
'lgbf-404zen',
__( '404Zen Pro', '404zen-broken-link-fixer' ),
__( 'Upgrade', '404zen-broken-link-fixer' ),
self::CAPABILITY,
'lgbf-404zen-upgrade',
array( __CLASS__, 'render_pricing' )
);
$contact_hook = add_submenu_page( 'lgbf-404zen', __( 'Contact', '404zen-broken-link-fixer' ), __( 'Contact', '404zen-broken-link-fixer' ), self::CAPABILITY, '404zen-support', array( __CLASS__, 'render_contact' ) );
add_action( "load-{$contact_hook}", array( __CLASS__, 'prepare_zen_page' ) );
add_action( "load-{$dashboard_hook}", array( __CLASS__, 'add_screen_options' ) );
foreach ( array( $dashboard_hook, $settings_hook, $pricing_hook ) as $hook ) {
add_action( "load-{$hook}", array( __CLASS__, 'prepare_zen_page' ) );
}
}
/**
* Full-bleed treatment: our pages own their canvas. Third-party admin
* notices are removed on 404Zen screens only (404Zen itself never
* adds admin-wide notices anywhere).
*/
public static function prepare_zen_page() {
remove_all_actions( 'admin_notices' );
remove_all_actions( 'all_admin_notices' );
add_filter(
'admin_body_class',
static function ( $classes ) {
return $classes . ' lgbf-zen';
}
);
}
/**
* Screen options (rows per page).
*/
public static function add_screen_options() {
add_screen_option(
'per_page',
array(
'label' => __( 'Links per page', '404zen-broken-link-fixer' ),
'default' => 25,
'option' => 'lgbf_links_per_page',
)
);
}
/**
* Persists the per-page screen option.
*
* @param mixed $status Default.
* @param string $option Option name.
* @param mixed $value Submitted value.
* @return mixed
*/
public static function save_screen_option( $status, $option, $value ) {
if ( 'lgbf_links_per_page' === $option ) {
return max( 1, min( 200, absint( $value ) ) );
}
return $status;
}
/**
* Registers the settings option.
*/
public static function register_settings() {
register_setting(
'lgbf_settings_group',
LGBF_Settings::OPTION_KEY,
array(
'type' => 'array',
'sanitize_callback' => array( 'LGBF_Settings', 'sanitize' ),
'default' => LGBF_Settings::defaults(),
)
);
}
/**
* Enqueues admin assets on 404Zen pages only.
*
* @param string $hook_suffix Current admin page.
*/
public static function enqueue_assets( $hook_suffix ) {
if ( false === strpos( (string) $hook_suffix, 'lgbf-404zen' ) ) {
return;
}
wp_enqueue_style( 'zen-admin', LGBF_PLUGIN_URL . 'assets/css/zen-admin.css', array(), LGBF_VERSION );
wp_enqueue_style( 'lgbf-admin', LGBF_PLUGIN_URL . 'assets/css/admin.css', array( 'zen-admin' ), LGBF_VERSION );
wp_enqueue_script( 'lgbf-admin', LGBF_PLUGIN_URL . 'assets/js/admin.js', array( 'jquery' ), LGBF_VERSION, true );
wp_localize_script(
'lgbf-admin',
'lgbfAdmin',
array(
'ajaxUrl' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce( 'lgbf_admin_nonce' ),
'i18n' => array(
'confirmUnlink' => __( 'Remove this link but keep its text?', '404zen-broken-link-fixer' ),
'dismissed' => __( 'Link dismissed — it will be ignored in future scans.', '404zen-broken-link-fixer' ),
'undo' => __( 'Undo', '404zen-broken-link-fixer' ),
'working' => __( 'Working…', '404zen-broken-link-fixer' ),
'error' => __( 'Something went wrong. Please try again.', '404zen-broken-link-fixer' ),
),
)
);
}
/**
* "Scan now" button handler.
*/
public static function handle_scan_now() {
if ( ! current_user_can( self::CAPABILITY ) ) {
wp_die( esc_html__( 'You are not allowed to do that.', '404zen-broken-link-fixer' ) );
}
check_admin_referer( 'lgbf_scan_now' );
LGBF_Scanner::request_immediate_scan();
spawn_cron();
wp_safe_redirect( add_query_arg( 'lgbf_notice', 'scan_started', admin_url( 'admin.php?page=lgbf-404zen' ) ) );
exit;
}
/**
* Processes list-table bulk actions before the page renders.
*/
public static function handle_bulk_actions() {
if ( ! current_user_can( self::CAPABILITY ) ) {
return;
}
$action = '';
foreach ( array( 'action', 'action2' ) as $key ) {
if ( isset( $_REQUEST[ $key ] ) && '-1' !== $_REQUEST[ $key ] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
$action = sanitize_key( wp_unslash( $_REQUEST[ $key ] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
break;
}
}
if ( ! $action || ! in_array( $action, array( 'recheck', 'dismiss', 'unlink' ), true ) ) {
return;
}
check_admin_referer( 'bulk-lgbf_links' );
$ids = isset( $_REQUEST['link_ids'] ) ? array_map( 'absint', (array) $_REQUEST['link_ids'] ) : array();
$ids = array_slice( array_filter( $ids ), 0, 100 );
if ( empty( $ids ) ) {
return;
}
$done = 0;
foreach ( $ids as $id ) {
switch ( $action ) {
case 'recheck':
$result = LGBF_Fixer::recheck( $id );
break;
case 'dismiss':
$result = LGBF_Fixer::dismiss( $id );
break;
case 'unlink':
$result = LGBF_Fixer::unlink( $id );
break;
default:
$result = null;
}
if ( true === $result || is_array( $result ) ) {
$done++;
}
}
wp_safe_redirect(
add_query_arg(
array(
'page' => 'lgbf-404zen',
'lgbf_notice' => 'bulk_done',
'lgbf_count' => $done,
),
admin_url( 'admin.php' )
)
);
exit;
}
/**
* The Zen Plugins top bar (lockup, tabs, docs, Go Pro).
*
* @param string $active dashboard|settings.
*/
private static function render_topbar( $active ) {
$docs_base = apply_filters( 'lgbf_docs_base', 'https://404zen.com/docs/' );
?>
0 ) { esc_html_e( 'Pro repairs them in one click and auto-redirects every dead URL — so you never lose another visitor.', '404zen-broken-link-fixer' ); } else { esc_html_e( 'Scheduled scans catch new breaks and auto-redirect them before a visitor ever hits a dead end.', '404zen-broken-link-fixer' ); } ?>
$
🛡
| 404Zen | ' . esc_html( $r[0] ) . ' | ✓ | ' . esc_html( $r[1] ) . ' | '; } ?>
|---|