gate = $gate;
$this->registry = $registry;
}
/**
* Module id.
*
* @since 1.0.0
*
* @return string
*/
public function id(): string {
return 'admin';
}
/**
* Module label.
*
* @since 1.0.0
*
* @return string
*/
public function label(): string {
return __( 'Admin interface', 'elevenrank' );
}
/**
* Registers the admin hooks.
*
* @since 1.0.0
*
* @return void
*/
public function boot(): void {
add_action( 'admin_menu', array( $this, 'register_menu' ) );
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_assets' ) );
( new Conflict_Notice( $this->gate ) )->hooks();
( new Activation_Redirect() )->hooks();
}
/**
* Adds the top-level menu.
*
* @since 1.0.0
*
* @return void
*/
public function register_menu(): void {
$this->hook_suffix = add_menu_page(
__( 'ElevenRank', 'elevenrank' ),
__( 'ElevenRank', 'elevenrank' ),
Capabilities::MANAGE,
self::MENU_SLUG,
array( $this, 'render_page' ),
self::MENU_ICON
);
}
/**
* Prints the element the React app mounts into.
*
* @since 1.0.0
*
* @return void
*/
public function render_page(): void {
?>
assets_available() ) : ?>
hook_suffix || $this->hook_suffix !== $hook_suffix ) {
return;
}
$asset = $this->read_asset_file();
if ( null === $asset ) {
return;
}
wp_enqueue_script(
self::HANDLE,
$this->build_url( 'admin-app.js' ),
$asset['dependencies'],
$asset['version'],
true
);
wp_set_script_translations( self::HANDLE, 'elevenrank' );
// The media picker (logo and sharing image fields) needs the WordPress media scripts.
wp_enqueue_media();
wp_add_inline_script(
self::HANDLE,
'window.elevenrankAdmin = ' . wp_json_encode(
array(
'version' => ELEVENRANK_VERSION,
'modules' => $this->registry->describe(),
'schemaTypes' => Type_Definitions::labels(),
)
) . ';',
'before'
);
wp_enqueue_style(
self::HANDLE,
$this->build_url( 'style-admin-app.css' ),
array( 'wp-components' ),
$asset['version']
);
wp_style_add_data( self::HANDLE, 'rtl', 'replace' );
}
/**
* Absolute path of a compiled file. `build/` is generated by `npm run build`, so it
* may legitimately be missing in a fresh checkout.
*
* @since 1.0.0
*
* @param string $file File name inside build/.
* @return string
*/
private function build_path( string $file ): string {
return ELEVENRANK_PATH . 'build/' . $file;
}
/**
* URL of a compiled file.
*
* @since 1.0.0
*
* @param string $file File name inside build/.
* @return string
*/
private function build_url( string $file ): string {
return ELEVENRANK_URL . 'build/' . $file;
}
/**
* Whether the compiled admin app exists.
*
* @since 1.0.0
*
* @return bool
*/
private function assets_available(): bool {
return null !== $this->read_asset_file();
}
/**
* Reads the dependency manifest that `wp-scripts build` generates.
*
* @since 1.0.0
*
* @return array{dependencies: string[], version: string}|null Null when the build is missing or malformed.
*/
private function read_asset_file(): ?array {
$path = $this->build_path( 'admin-app.asset.php' );
if ( ! is_readable( $path ) ) {
return null;
}
$asset = require $path;
if ( ! is_array( $asset ) || ! isset( $asset['dependencies'], $asset['version'] ) || ! is_array( $asset['dependencies'] ) ) {
return null;
}
return array(
'dependencies' => array_map( 'strval', $asset['dependencies'] ),
'version' => (string) $asset['version'],
);
}
}