true, 'pending' => true, ) ), $retired ) ) ) ); } /** * Check a public page's markup for a source: whether it offers the source's copies. * * @param array $r The source row. * @return array The check. * @throws \RuntimeException With a reason code as its message when the step cannot be done. */ public static function check_row( array $r ): array { $im_reviewed_owner_lock = Reviewed_Store::enter(); try { if ( ! Sources::eligible( $r ) ) { throw new \RuntimeException( 'preview_public_required' ); } $page = self::page( $r ); $cache = 'afsd_im_htmlcheck_' . substr( hash( 'sha256', $page ), 0, 32 ); $response = get_transient( $cache ); if ( ! is_array( $response ) || ( $response['expires'] ?? 0 ) < time() ) { $response = Urls::fetch( $page ); if ( ! is_wp_error( $response ) ) { $response['expires'] = time() + 60; Reviewed_Store::set_transient( $cache, $response, 60 ); } } $check = array( 'signature' => self::signature( $r ), 'time' => time(), 'page' => $page, 'kind' => 'public_html', 'status' => 'unavailable', 'matches' => 0, 'native_matches' => 0, 'older_matches' => 0, 'coverage' => Delivery::coverage( $r ), ); if ( is_wp_error( $response ) ) { $check['reason'] = sanitize_key( $response->get_error_code() ); } else { $seen = self::markup_urls( $response['html'], $response['url'] ); $active = self::urls( $r ); $history = array_diff( self::urls( $r, true ), $active ); $current = array_values( array_intersect( $seen, $active ) ); $old = array_intersect( $seen, $history ); $native = array_intersect( $seen, (array) ( $r['details']['urls'] ?? array() ) ); $check['status'] = $current ? 'offered' : ( $old ? 'older' : ( $native ? 'original' : ( ! $active ? 'no_files' : 'not_found' ) ) ); $check['matches'] = count( $current ); $check['native_matches'] = count( $native ); $check['older_matches'] = count( $old ); } $fresh = Repository::row( (int) $r['id'] ); if ( $fresh && self::signature( $fresh ) === $check['signature'] ) { $d = $fresh['details']; $d['delivery_check'] = $check; Repository::update( (int) $r['id'], array( 'details' => $d ), (int) $r['revision'] ); } return $check; } finally { Reviewed_Store::leave( $im_reviewed_owner_lock ); } } /** * The picture addresses a page's markup offers (img and source elements), within the page's own origin. * * @param string $html The page. * @param string $page Its address. * @return array The addresses, or an empty array for a page over 2 MB. */ public static function markup_urls( string $html, string $page ): array { if ( strlen( $html ) > 2097152 ) { return array(); }$p = new \WP_HTML_Tag_Processor( $html ); $urls = array(); $n = 0; $blocked = 0; while ( $n++ < 8000 && $p->next_tag( array( 'tag_closers' => 'visit' ) ) ) { $tag = $p->get_tag(); $close = $p->is_tag_closer(); if ( 'BASE' === $tag ) { return array(); } if ( in_array( $tag, array( 'NOSCRIPT', 'TEMPLATE', 'SVG', 'VIDEO', 'AUDIO' ), true ) ) { $blocked = $close ? max( 0, $blocked - 1 ) : $blocked + 1; continue; } if ( $blocked || $close || ! in_array( $tag, array( 'IMG', 'SOURCE' ), true ) ) { continue; } $src = $p->get_attribute( 'src' ); if ( is_string( $src ) ) { $urls[] = Urls::absolute( $src, $page ); } $set = $p->get_attribute( 'srcset' );if ( is_string( $set ) ) { $parsed = Urls::srcset( $set ); if ( $parsed ) { foreach ( $parsed as $c ) { $urls[] = Urls::absolute( $c['url'], $page ); } } elseif ( ! str_contains( $set, ',' ) && preg_match( '/^\s*([^\s]+)\s*$/D', $set, $single ) ) { $urls[] = Urls::absolute( html_entity_decode( $single[1], ENT_QUOTES | ENT_HTML5, 'UTF-8' ), $page ); } } if ( count( $urls ) > 2048 ) { break; } }return array_values( array_unique( $urls ) ); } /** * The words for a source's latest delivery check, when it still matches what the source delivers. * * @param array $r The source row. * @return string The translated words. */ public static function label( array $r ): string { $b = $r['details']['browser_check'] ?? array(); $h = $r['details']['delivery_check'] ?? array(); $sig = self::signature( $r ); if ( ( $b['signature'] ?? '' ) === $sig && time() - (int) $b['time'] < 86400 ) { return ( ! empty( $b['optimized'] ) ? __( 'This signed-in browser loaded optimized files', 'affstackdev-image-manager' ) : ( ! empty( $b['original'] ) ? __( 'This signed-in browser loaded the original', 'affstackdev-image-manager' ) : __( 'Image not observed as loaded in this signed-in check', 'affstackdev-image-manager' ) ) ) . ' · ' . gmdate( 'H:i', (int) $b['time'] ) . ' UTC'; } if ( ( $h['signature'] ?? '' ) === $sig && time() - (int) $h['time'] < 86400 ) { $status = $h['status'] ?? ''; $current = (int) ( $h['matches'] ?? 0 ); $native = (int) ( $h['native_matches'] ?? 0 ); if ( 'offered' === $status ) { $text = __( 'Public page offers current optimized files', 'affstackdev-image-manager' ); if ( $current ) { /* translators: %d: number of current optimized file URLs the public page offers. */ $text .= sprintf( _n( ' (%d current URL)', ' (%d current URLs)', $current, 'affstackdev-image-manager' ), $current ); }if ( $native ) { $text .= __( '; original fallback/candidates are also present', 'affstackdev-image-manager' ); }$text .= __( '; browser not checked', 'affstackdev-image-manager' ); } elseif ( 'older' === $status ) { $text = __( 'Public page still references older managed copies. Refresh ordinary page/CDN caches before diagnosing current delivery.', 'affstackdev-image-manager' ); } elseif ( 'original' === $status ) { $c = $h['coverage'] ?? Delivery::coverage( $r ); $complete = ! empty( $c['complete_managed_mime_families'] ); $text = $complete ? __( 'Public page offers the original even though stored optimized coverage is complete; cache or this output integration needs review.', 'affstackdev-image-manager' ) : __( 'Public page offers the original and stored optimized coverage is incomplete for this image family.', 'affstackdev-image-manager' ); } else { $map = array( 'no_files' => __( 'No optimized files available for this image', 'affstackdev-image-manager' ), 'not_found' => __( 'Image not found in checked public markup', 'affstackdev-image-manager' ), 'unavailable' => __( 'Public-page check could not finish', 'affstackdev-image-manager' ), ); $text = $map[ $status ] ?? __( 'Delivery not checked', 'affstackdev-image-manager' ); } return $text . ' · ' . gmdate( 'H:i', (int) $h['time'] ) . ' UTC'; } return __( 'Website delivery not checked for these files yet', 'affstackdev-image-manager' ); } /** * The address of the browser inspector for a source (with a nonce). * * @param int $id The source row. * @return string The address. */ public static function inspector_url( int $id ): string { return add_query_arg( array( 'action' => 'afsd_im_inspect', 'source' => $id, '_wpnonce' => wp_create_nonce( 'afsd_im_inspect_' . $id ), ), admin_url( 'admin-post.php' ) ); } /** * Record what the owner's browser loaded for a source on its page. * * @param int $id The source row. * @param string $signature The signature the inspector was opened with. * @param array $observations The files the browser reported loading. * @param int $width The browser's viewport width. * @param float $dpr Its device pixel ratio. * @return string The translated result. * @throws \RuntimeException With delivery_check_stale when the source changed since the inspector opened. */ public static function browser_record( int $id, string $signature, array $observations, int $width, float $dpr ): string { $im_reviewed_owner_lock = Reviewed_Store::enter(); try { $r = Preview::row( $id ); if ( ! Sources::eligible( $r ) || ! hash_equals( self::signature( $r ), $signature ) ) { throw new \RuntimeException( 'delivery_check_stale' ); } if ( $width < 240 || $width > 2560 || $dpr < 0.5 || $dpr > 8 || count( $observations ) > 256 ) { throw new \RuntimeException( 'delivery_invalid_result' ); } $active = self::urls( $r ); $natives = $r['details']['urls'] ?? array(); $optimized = 0; $original = 0; foreach ( $observations as $o ) { if ( ! is_array( $o ) || ! is_string( $o['url'] ?? null ) || empty( $o['loaded'] ) || ! is_numeric( $o['width'] ?? null ) || (int) $o['width'] < 1 ) { continue; } if ( in_array( $o['url'], $active, true ) ) { ++$optimized; } elseif ( in_array( $o['url'], $natives, true ) ) { ++$original; } } $d = $r['details']; $d['browser_check'] = array( 'signature' => $signature, 'time' => time(), 'width' => $width, 'dpr' => $dpr, 'optimized' => $optimized, 'original' => $original, 'kind' => 'signed_in_browser', ); Repository::update( $id, array( 'details' => $d ), (int) $r['revision'] ); if ( $optimized ) { return __( 'This browser loaded optimized files. This signed-in diagnostic does not certify anonymous cached visitors.', 'affstackdev-image-manager' ); } if ( $original ) { $c = Delivery::coverage( $r ); return empty( $c['complete_managed_mime_families'] ) ? __( 'This browser loaded the original. Stored optimized coverage is incomplete for this image family; review size results before blaming cache.', 'affstackdev-image-manager' ) : __( 'This browser loaded the original even though stored optimized coverage is complete. Check public markup, cache state, and whether this output surface uses the supported delivery path.', 'affstackdev-image-manager' ); } return __( 'This image was not observed as loaded. It may be lazy-loaded, absent, or blocked from this inspection.', 'affstackdev-image-manager' ); } finally { Reviewed_Store::leave( $im_reviewed_owner_lock ); } } /** * The browser inspector: a GET for a source with a valid nonce, answered as the inspector page or the recorded result. * * @throws \RuntimeException Only inside this function, where it is caught; callers get no exception. */ public static function inspector(): void { try { if ( ! current_user_can( 'manage_options' ) || ! current_user_can( 'upload_files' ) ) { throw new \RuntimeException( 'image_access_denied' ); } $get = Plugin::fields( array( 'source', '_wpnonce' ), true ); $id = is_scalar( $get['source'] ?? null ) ? absint( $get['source'] ) : 0; $method = isset( $_SERVER['REQUEST_METHOD'] ) && is_string( $_SERVER['REQUEST_METHOD'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REQUEST_METHOD'] ) ) : ''; if ( 'GET' !== $method ) { throw new \RuntimeException( 'image_access_denied' ); } if ( ! isset( $get['_wpnonce'] ) || ! is_string( $get['_wpnonce'] ) || ! wp_verify_nonce( $get['_wpnonce'], 'afsd_im_inspect_' . $id ) ) { throw new \RuntimeException( 'image_access_denied' ); } $r = Preview::row( $id ); if ( ! Sources::eligible( $r ) ) { throw new \RuntimeException( 'preview_public_required' ); }$page = self::page( $r ); nocache_headers(); header( 'Cache-Control: private, no-store, max-age=0' ); header( 'Referrer-Policy: same-origin' ); header( 'X-Content-Type-Options: nosniff' ); header( 'Content-Type: text/html; charset=utf-8' ); wp_enqueue_script( 'afsd-im-inspector', plugins_url( 'assets/inspector.js', FILE ), array(), VERSION, true ); wp_localize_script( 'afsd-im-inspector', 'afsdImageManagerInspector', array( 'widthChanged' => __( 'Preview width changed. Allow responsive images to settle, then check again.', 'affstackdev-image-manager' ), 'loaded' => __( 'Preview loaded. Scroll inside it to the image, then click Check loaded images.', 'affstackdev-image-manager' ), 'noImages' => __( 'Preview unavailable, blocked from embedding, or contains no images.', 'affstackdev-image-manager' ), 'foreignEndpoint' => __( 'The diagnostic endpoint is not on this website.', 'affstackdev-image-manager' ), 'notSaved' => __( 'The result could not be saved.', 'affstackdev-image-manager' ), 'evidence' => __( 'Observed selected image URLs (not transfer-size measurements):', 'affstackdev-image-manager' ), /* translators: %d: the image's intrinsic width in pixels. */ 'intrinsicWidth' => __( 'intrinsic width %d', 'affstackdev-image-manager' ), 'failed' => __( 'This preview could not be inspected.', 'affstackdev-image-manager' ), ) ); echo '' . esc_html__( 'Image delivery check', 'affstackdev-image-manager' ) . ''; // The page's own styles, through WordPress's style queue like its script. wp_register_style( 'afsd-im-inspector', false, array(), VERSION ); wp_add_inline_style( 'afsd-im-inspector', 'body{font:16px/1.5 system-ui;margin:24px;background:#f5f7fb;color:#142136}main{max-width:1400px;margin:auto}' . 'button,select,a{font:inherit;padding:8px}section{background:white;padding:16px;border:1px solid #ccd4e3;border-radius:8px;margin:16px 0}' . '.frame{overflow:auto}iframe{height:560px;max-width:none;border:1px solid #ccd4e3}pre{white-space:pre-wrap;overflow-wrap:anywhere}' ); wp_print_styles( array( 'afsd-im-inspector' ) ); echo '

' . esc_html__( 'Check what this browser loads', 'affstackdev-image-manager' ) . '

' /* translators: %s: the words "signed-in diagnostic", shown in bold. */ . sprintf( esc_html__( 'This is a %s of a known public page, not a test of anonymous cached visitors. Only this inspection tab runs the check. Scroll inside the preview to load an image below the fold, then check again.', 'affstackdev-image-manager' ), '' . esc_html__( 'signed-in diagnostic', 'affstackdev-image-manager' ) . '' ) . '

' . esc_html__( 'Return to Image Manager', 'affstackdev-image-manager' ) . '

' . esc_html__( 'Waiting for the preview. Sites that block embedding cannot be inspected here.', 'affstackdev-image-manager' ) . '

'; wp_print_scripts( array( 'afsd-im-inspector' ) ); echo ''; exit; } catch ( \Throwable $e ) { wp_die( esc_html__( 'This image inspection is unavailable or access expired. Return to Image Manager.', 'affstackdev-image-manager' ), '', array( 'response' => 403 ) ); } } }