$names The arguments' names. * @return array */ public static function values( array $names ): array { if ( ! isset( $_GET['rooster_view'] ) || ! wp_verify_nonce( sanitize_key( wp_unslash( $_GET['rooster_view'] ) ), 'rooster_admin_view' ) ) { return array(); } $out = array(); foreach ( $names as $name ) { $name = (string) $name; if ( isset( $_GET[ $name ] ) ) { $out[ $name ] = map_deep( wp_unslash( $_GET[ $name ] ), 'sanitize_text_field' ); } } return $out; } /** * The data of assets/view.js (window.roosterAdminView), where it loads (Library::enqueue()): the person's view * nonce, the Rooster pages' slugs (pages()), wp-admin's path, and whether this request's address carried a valid * nonce (view_ok()). * * @param Registry $registry The booted registry. * @return array{nonce: string, pages: list, admin: string, ok: bool} */ public static function view_data( Registry $registry ): array { return array( 'nonce' => wp_create_nonce( self::VIEW_ACTION ), 'pages' => self::pages( $registry ), 'admin' => (string) wp_parse_url( admin_url(), PHP_URL_PATH ), 'ok' => self::view_ok(), ); } /** * The Rooster pages' slugs (0.81.0, from view_data()): every product's Home and every page a catalogue entry names. * * @param Registry $registry The booted registry. * @return list */ public static function pages( Registry $registry ): array { $pages = array(); foreach ( $registry->products() as $product ) { $pages[] = (string) ( $product['home']['slug'] ?? '' ); } foreach ( $registry->visible( null ) as $entry ) { $pages[] = (string) ( $entry['args']['page'] ?? '' ); } return array_values( array_unique( array_filter( $pages ) ) ); } /** * Whether the request's address carries a valid view nonce (assets/view.js keeps the address bar's nonce current * only then). */ public static function view_ok(): bool { if ( ! isset( $_GET['rooster_view'] ) || ! wp_verify_nonce( sanitize_key( wp_unslash( $_GET['rooster_view'] ) ), 'rooster_admin_view' ) ) { return false; } return true; } /** * $url with the view nonce when it is a wp-admin page's address with view arguments (beside `page`, `post_type` and * `taxonomy`, WordPress's own routing) and this is * a wp-admin request (the library's own links: a filter chip, Clear filters, a pager, a menu entry's tab); as it is * otherwise (a storefront table's links stay plain: a public page carries no nonce; a bare page's address has no * view argument to guard). * * @param string $url An address. */ public static function view_url( string $url ): string { if ( '' === $url || ! is_admin() ) { return $url; } $query = (string) wp_parse_url( $url, PHP_URL_QUERY ); $args = array(); wp_parse_str( $query, $args ); $page = (string) ( $args['page'] ?? '' ); unset( $args[ self::VIEW_ARG ], $args['page'], $args['post_type'], $args['taxonomy'] ); // WordPress's own routing is no view argument $path = (string) wp_parse_url( $url, PHP_URL_PATH ); $admin = (string) wp_parse_url( admin_url(), PHP_URL_PATH ); $here = '' === $path || ! str_contains( $path, '/' ) || str_starts_with( $path, $admin ); // relative to wp-admin, or in it if ( '' === $page || array() === $args || ! $here ) { return $url; } return rooster_admin_view_url( $url ); } /** * The view nonce's hidden field for a GET form, in wp-admin ('' elsewhere). */ public static function view_field(): string { return is_admin() ? rooster_admin_view_field() : ''; } /** * The address the request names (esc_url_raw()); '' when the server gives none. */ public static function uri(): string { return isset( $_SERVER['REQUEST_URI'] ) && is_string( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : ''; } /** * The arguments of the page's own address (uri()), for a GET form that must come back to the same screen: names of * letters, digits, `_` and `-`, single values as lines of text, the view nonce left out (the form prints its own, * rooster_admin_view_field()). Taken from the sanitised address, not the request's arguments, and only ever printed * back as hidden fields of that form. * * @return array */ public static function address(): array { $args = array(); wp_parse_str( (string) wp_parse_url( self::uri(), PHP_URL_QUERY ), $args ); $out = array(); foreach ( $args as $name => $value ) { $name = (string) $name; if ( self::VIEW_ARG !== $name && is_scalar( $value ) && 1 === preg_match( '/^[A-Za-z0-9_-]+$/', $name ) ) { $out[ $name ] = sanitize_text_field( (string) $value ); } } return $out; } }