connect = $connect;
$this->settings = new AdvisorPPC_Settings();
}
/**
* Register hooks.
*
* @param AdvisorPPC_Loader $loader Hook loader.
* @return void
*/
public function register( $loader ) {
$this->settings->register( $loader );
$loader->add_action( 'admin_menu', $this, 'add_menu' );
$loader->add_action( 'admin_enqueue_scripts', $this, 'enqueue_assets' );
$loader->add_action( 'admin_notices', $this, 'render_notices' );
$loader->add_action( 'admin_post_advisorppc_clear_log', $this, 'handle_clear_log' );
$loader->add_action( 'admin_post_advisorppc_tracktor_enable', $this, 'handle_tracktor_enable' );
$loader->add_action( 'admin_post_advisorppc_detect_scan', $this, 'handle_detect_scan' );
$loader->add_action( 'admin_post_advisorppc_detect_apply', $this, 'handle_detect_apply' );
$loader->add_action( 'admin_post_advisorppc_detect_dismiss', $this, 'handle_detect_dismiss' );
$loader->add_action( 'admin_post_advisorppc_detect_undo', $this, 'handle_detect_undo' );
$loader->add_filter( 'plugin_action_links_' . plugin_basename( ADVISORPPC_PLUGIN_FILE ), $this, 'action_links' );
}
/**
* Add the top-level menu.
*
* @return void
*/
public function add_menu() {
$this->hook_suffix = add_menu_page(
__( 'AdvisorPPC', 'advisorppc' ),
__( 'AdvisorPPC', 'advisorppc' ),
'manage_options',
self::SLUG,
array( $this, 'render_page' ),
self::menu_icon(),
58
);
}
/**
* Read one of the shipped brand SVGs for inline output.
*
* Inline rather than an `
` because the marks use `currentColor`: an
* image-loaded SVG has no access to the host document's colour, so it would
* render black on the dark admin scheme. Inlining is also one fewer request
* on a screen that already loads a stylesheet.
*
* Returns '' rather than a placeholder when the file is missing, so a
* broken asset degrades to a text-only heading instead of a broken image.
*
* @param string $name File stem inside assets/brand, no extension.
* @param string $class Optional class attribute for the root element.
* @return string Raw SVG markup, or ''.
*/
public static function brand_svg( $name, $class = 'advisorppc-brand-svg' ) {
$name = preg_replace( '/[^a-z0-9\-]/', '', strtolower( (string) $name ) );
if ( '' === $name ) {
return '';
}
$path = ADVISORPPC_PLUGIN_DIR . 'assets/brand/' . $name . '.svg';
if ( ! is_readable( $path ) ) {
return '';
}
// phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents -- local plugin asset, not a remote fetch.
$svg = file_get_contents( $path );
if ( ! is_string( $svg ) ) {
return '';
}
// Drop the XML prolog and any comment block; neither belongs inline.
$svg = preg_replace( '/<\?xml.*?\?>/s', '', $svg );
$svg = preg_replace( '//s', '', $svg );
$svg = trim( (string) $svg );
if ( '' === $class ) {
return $svg;
}
return preg_replace(
'/