= 0; got %d.', $position ); // phpcs:ignore WordPress.Security.EscapeOutput.ExceptionNotEscaped -- Developer-facing message, never rendered to HTML. throw new InvalidArgumentException( $message ); } $this->parentSlug = $parentSlug; $this->pageTitle = $pageTitle; $this->menuTitle = $menuTitle; $this->capability = $capability; $this->menuSlug = $menuSlug; $this->renderCallback = $renderCallback; $this->iconUrl = $iconUrl; $this->position = $position; $this->loadCallback = $loadCallback; } /** * Return the WordPress parent-menu slug; empty string for * top-level menus. */ public function parentSlug(): string { return $this->parentSlug; } /** * Return the page-title argument forwarded to * `add_menu_page()` / `add_submenu_page()`. */ public function pageTitle(): string { return $this->pageTitle; } /** * Return the menu-title argument forwarded to * `add_menu_page()` / `add_submenu_page()`. */ public function menuTitle(): string { return $this->menuTitle; } /** * Return the required capability literal. */ public function capability(): string { return $this->capability; } /** * Return the URL-bound menu slug. */ public function menuSlug(): string { return $this->menuSlug; } /** * Return the page-render callable. * * @return callable * * @phpstan-return callable(): void */ public function renderCallback(): callable { return $this->renderCallback; } /** * Return the top-level menu icon URL (ignored for submenus). */ public function iconUrl(): string { return $this->iconUrl; } /** * Return the menu position; `0` means "unset". */ public function position(): int { return $this->position; } /** * Return the optional page-load callable; null when no * load-time hook is needed. * * @return callable|null * * @phpstan-return (callable(): void)|null */ public function loadCallback(): ?callable { return $this->loadCallback; } /** * Report whether this definition describes a top-level menu * (i.e. `parentSlug` is the empty string). */ public function isTopLevel(): bool { return $this->parentSlug === ''; } /** * Report whether `$other` describes the same admin-page * registration as this definition. * * Equality is structural over the string and integer fields; * the `renderCallback` / `loadCallback` callables are compared * by reference identity (`===`), which matches the registrar's * forwarding semantics. * * @param self $other Definition to compare against. */ public function equals( self $other ): bool { return $this->parentSlug === $other->parentSlug && $this->pageTitle === $other->pageTitle && $this->menuTitle === $other->menuTitle && $this->capability === $other->capability && $this->menuSlug === $other->menuSlug && $this->iconUrl === $other->iconUrl && $this->position === $other->position && $this->renderCallback === $other->renderCallback && $this->loadCallback === $other->loadCallback; } }