getFileName(); // Library.php sits in the copy's includes/ folder: the copy's folder is cut from that path as a string (a // wordpress.org review gate rejects a dirname() that climbs levels, 1 Nov 2026). $dir = rtrim( str_replace( '\\', '/', dirname( $file ) ), '/' ); if ( str_ends_with( $dir, '/includes' ) ) { $dir = substr( $dir, 0, -9 ); } $real = rtrim( str_replace( '\\', '/', (string) realpath( $dir ) ), '/' ); // The registered folder may reach the copy through a junction or a symbolic link while PHP names the included // file by its real path: the two are compared as real paths, and the registered spelling is what is returned // (the URLs are keyed by it). foreach ( array( 'rooster_admin_candidates', 'rooster_admin_copies' ) as $list ) { $known = is_array( $GLOBALS[ $list ] ?? null ) ? array_keys( $GLOBALS[ $list ] ) : array(); foreach ( $known as $registered ) { $spelled = rtrim( str_replace( '\\', '/', (string) $registered ), '/' ); if ( $spelled === $dir || ( '' !== $real && rtrim( str_replace( '\\', '/', (string) realpath( $spelled ) ), '/' ) === $real ) ) { return (string) $registered; } } } return $dir; } } if ( ! function_exists( 'rooster_admin_rest' ) ) { /** * Hook rest_api_init (99): the newest registered copy registers the preferences route, for a signed-in user only, * unless a copy is already in this process (rooster_admin_loaded()), which then serves it. A visitor's REST request * registers nothing; a page never reaches this. */ function rooster_admin_rest(): void { if ( ! is_user_logged_in() ) { return; } $dir = rooster_admin_loaded(); if ( '' === $dir ) { $candidates = $GLOBALS['rooster_admin_candidates'] ?? array(); $dir = is_array( $candidates ) ? rooster_admin_newest( $candidates ) : ''; if ( '' === $dir ) { return; } require_once $dir . '/includes/Library.php'; } $urls = $GLOBALS['rooster_admin_urls'] ?? array(); \Rooster\Admin\Library::rest( $dir, is_array( $urls ) && is_string( $urls[ $dir ] ?? null ) ? $urls[ $dir ] : '' ); } } if ( ! function_exists( 'rooster_admin_builders' ) ) { /** * The library's builders outside a chrome screen (0.63.0, CONTRACT ยง8.2): Ui::table(), Ui::rows(), Ui::answer(), the * fields and the states, for a remote table's route (REST, admin-ajax) and a storefront table. The newest noted copy * loads its builder classes on demand; nothing else boots (no registry, no chrome). On the storefront the icons the * table drew get their sprite in the footer. A storefront table's scripts are rooster_table_engine()'s. * * @return bool Whether the builders are there (false: no copy of the library is registered). */ function rooster_admin_builders(): bool { if ( class_exists( '\\Rooster\\Admin\\Ui', false ) ) { return true; } $copies = is_array( $GLOBALS['rooster_admin_copies'] ?? null ) ? $GLOBALS['rooster_admin_copies'] : array(); $dir = rooster_admin_loaded(); if ( '' === $dir ) { $dir = rooster_admin_newest( array_map( static fn( array $copy ): string => (string) $copy[0], $copies ) ); if ( '' === $dir ) { return false; } require_once $dir . '/includes/Library.php'; } \Rooster\Admin\Library::builders( $dir, (string) ( $copies[ $dir ][1] ?? '' ) ); return true; } } if ( ! function_exists( 'rooster_admin_newest' ) ) { /** * The folder of the newest registered copy ('' without any): the highest version; of equal versions, the first * registered. * * @param array $candidates Folder => version. */ function rooster_admin_newest( array $candidates ): string { $best = ''; $version = ''; foreach ( $candidates as $dir => $candidate ) { if ( '' === $best || version_compare( (string) $candidate, $version, '>' ) ) { $best = (string) $dir; $version = (string) $candidate; } } return $best; } } if ( ! function_exists( 'rooster_admin_skips_boot' ) ) { /** * Whether an admin request boots no chrome: a visitor's admin-ajax request (a cart add, a booking widget) never * draws it, and the boot cost each one 30 to 34 ms (rooster-one-72, 29 Oct 2026). A signed-in user's AJAX keeps the * boot (the admin's screens call back); a table a visitor's request renders asks for rooster_admin_builders(), which * needs no boot. */ function rooster_admin_skips_boot(): bool { return wp_doing_ajax() && ! is_user_logged_in(); } } if ( ! function_exists( 'rooster_admin_boot' ) ) { /** * Hook init (5): boots the newest registered copy once, unless the request draws no chrome * (rooster_admin_skips_boot()). */ function rooster_admin_boot(): void { if ( rooster_admin_skips_boot() ) { return; } if ( class_exists( '\Rooster\Admin\Library', false ) && \Rooster\Admin\Library::booted() ) { return; } $dir = rooster_admin_loaded(); if ( '' === $dir ) { $candidates = $GLOBALS['rooster_admin_candidates'] ?? array(); $dir = is_array( $candidates ) ? rooster_admin_newest( $candidates ) : ''; if ( '' === $dir ) { return; } require_once $dir . '/includes/Library.php'; } $urls = $GLOBALS['rooster_admin_urls'] ?? array(); \Rooster\Admin\Library::boot( $dir, is_array( $urls ) && is_string( $urls[ $dir ] ?? null ) ? $urls[ $dir ] : '' ); } } /* * The view nonce (0.69.0, the wordpress.org review: every read of a request argument is in a function that checks a * nonce). A Rooster screen's view arguments (its tab, filters, search, sort, page number, the object it shows) are * read only when the address carries `rooster_view`, a nonce of the action `rooster_admin_view`, one for every screen of * every product; without it the screen shows its default view. These two names are the contract (docs/CONTRACT.md): * a product that builds a link to a Rooster screen where the library is not loaded computes the same nonce itself. */ if ( ! function_exists( 'rooster_admin_view_url' ) ) { /** * $url with the current user's view nonce (added, or put in place of an older one), the rest of the address as it * was: appended before the fragment, never through add_query_arg(), which would re-encode a template's `%d`. * * @param string $url An admin address (not escaped: the caller escapes it where it prints it). */ function rooster_admin_view_url( string $url ): string { $hash = strpos( $url, '#' ); $fragment = false === $hash ? '' : substr( $url, $hash ); $url = false === $hash ? $url : substr( $url, 0, $hash ); $url = rtrim( (string) preg_replace( '/([?&])rooster_view=[^&]*(?:&|$)/', '$1', $url ), '?&' ); return $url . ( str_contains( $url, '?' ) ? '&' : '?' ) . 'rooster_view=' . rawurlencode( wp_create_nonce( 'rooster_admin_view' ) ) . $fragment; } } if ( ! function_exists( 'rooster_admin_view_field' ) ) { /** * The hidden field that carries the view nonce in a GET form to a Rooster screen (a filter bar, a search box). */ function rooster_admin_view_field(): string { return ''; } } if ( ! function_exists( 'rooster_admin' ) ) { /** * The booted library's registry, or null before `init` or outside the admin. * * @return \Rooster\Admin\Registry|null */ function rooster_admin(): ?\Rooster\Admin\Registry { return class_exists( '\Rooster\Admin\Library', false ) ? \Rooster\Admin\Library::registry() : null; } }