post_type || 'trash' === $post->post_status || ! current_user_can( 'edit_post', $id ) ) { throw new \RuntimeException( 'image_access_denied' ); } /* translators: %d: Attachment ID. */ $title = $post->post_title ?: sprintf( __( 'Media #%d', 'affstackdev-image-manager' ), $id ); $meta = wp_get_attachment_metadata( $id ); $meta = is_array( $meta ) ? $meta : array(); $org = Library::organization_for_objects( array( $id ) ); $org = $org[ $id ] ?? array( 'folders' => array(), 'collections' => array(), ); $pdf = 'application/pdf' === (string) $post->post_mime_type; $row = $pdf ? null : Repository::attachment( $id ); $image = str_starts_with( (string) $post->post_mime_type, 'image/' ); $pdf_preview = $pdf ? Media_Display::pdf_preview( $id, $meta, true ) : array(); echo '
' . esc_html__( 'Saved first-page preview', 'affstackdev-image-manager' ) . '
'; } elseif ( $pdf ) { echo '' . esc_html__( 'No suitable saved preview is available. You can still open and organize this PDF.', 'affstackdev-image-manager' ) . '
' . esc_html( get_post_meta( $id, '_wp_attachment_image_alt', true ) ?: __( 'No default description saved.', 'affstackdev-image-manager' ) ) . '
'; } if ( $post->post_excerpt ) { echo '' . esc_html( $post->post_excerpt ) . '
'; } if ( $image ) { self::photo_details( $id, $meta, $post ); } echo '' . esc_html__( 'This PDF can be organized in folders and collections and included in media backups. Create image from PDF can render one page as a separate image on supported hosts. PDF contents are not changed by image compression.', 'affstackdev-image-manager' ) . '
'; } elseif ( $row ) { $result = Results::row( $row ); echo '' . esc_html( $result['label'] ) . '
' . esc_html( $result['reason'] ) . '
' . esc_html( $result['delivery'] ) . '
'; echo '' . esc_html__( 'Optimization details and delivery checks', 'affstackdev-image-manager' ) . ''; } else { echo '' . esc_html__( 'No optimization record for this attachment yet.', 'affstackdev-image-manager' ) . '
'; } Media_Usage::render( $id, $back_url ); $parent = (int) $post->post_parent; if ( $parent && current_user_can( 'edit_post', $parent ) && get_post( $parent ) && 'trash' !== get_post_status( $parent ) ) { /* translators: %d: Parent content ID. */ echo '' . esc_html__( 'Upload association:', 'affstackdev-image-manager' ) . ' ' . esc_html( get_the_title( $parent ) ?: sprintf( __( 'Content #%d', 'affstackdev-image-manager' ), $parent ) ) . '. ' . esc_html__( 'This attachment relationship alone does not establish current use.', 'affstackdev-image-manager' ) . '
'; } echo '' . esc_html( $shown ? __( 'Up to 16 references previously recorded by the optimizer are shown. These have not been rechecked here; inspect current content before relying on them.', 'affstackdev-image-manager' ) : __( 'No accessible references are recorded here. This does not mean the file is unused.', 'affstackdev-image-manager' ) ) . '
'; $history = $image ? array_slice( array_reverse( Editor::history( $id ) ), 0, 5 ) : array(); if ( $history ) { echo '' . esc_html__( 'The original file holds GPS coordinates (where the photo was taken). Anyone who opens its address can read them. Image Manager’s copies leave them out when the compression choice removes GPS.', 'affstackdev-image-manager' ) . '
'; } $caption = '' !== trim( (string) ( $m['caption'] ?? '' ) ) && '' === trim( (string) $post->post_excerpt ); $title = '' !== trim( (string) ( $m['title'] ?? '' ) ) && Auto_Text::copied_title( $id, (string) $post->post_title ); if ( $caption || $title ) { echo ''; } } /** * Whether the original JPEG still holds GPS coordinates (PHP's exif extension; nothing is shown without it). * * @param int $id The attachment. * @return bool */ private static function has_location( int $id ): bool { $file = function_exists( 'wp_get_original_image_path' ) ? wp_get_original_image_path( $id ) : get_attached_file( $id ); if ( ! function_exists( 'exif_read_data' ) || ! is_string( $file ) || ! is_file( $file ) || filesize( $file ) > 67108864 || 'image/jpeg' !== wp_get_image_mime( $file ) ) { return false; } set_error_handler( static fn() => true ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_set_error_handler -- a damaged EXIF block only means "no location"; its warnings are not the page's. try { $exif = exif_read_data( $file, 'GPS', true ); } finally { restore_error_handler(); } return is_array( $exif ) && ! empty( $exif['GPS']['GPSLatitude'] ) && ! empty( $exif['GPS']['GPSLongitude'] ); } /** * Copy the photo's own caption (when the caption is empty) and title (when the title is the bare file name). * * @param int $id The attachment. * @return array The fields filled (caption, title). * @throws \RuntimeException When the attachment may not be changed or the change fails. */ public static function copy_photo_text( int $id ): array { $lock = Reviewed_Store::enter( 8 ); try { $post = get_post( $id ); if ( ! $post || 'attachment' !== $post->post_type || ! current_user_can( 'edit_post', $id ) ) { throw new \RuntimeException( 'image_access_denied' ); } $meta = wp_get_attachment_metadata( $id ); $m = is_array( $meta ) && isset( $meta['image_meta'] ) && is_array( $meta['image_meta'] ) ? $meta['image_meta'] : array(); $update = array( 'ID' => $id ); $done = array(); $text = sanitize_textarea_field( (string) ( $m['caption'] ?? '' ) ); if ( '' !== trim( $text ) && '' === trim( (string) $post->post_excerpt ) ) { $update['post_excerpt'] = $text; $done[] = 'caption'; } $text = sanitize_text_field( (string) ( $m['title'] ?? '' ) ); if ( '' !== trim( $text ) && Auto_Text::copied_title( $id, (string) $post->post_title ) ) { $update['post_title'] = $text; $done[] = 'title'; } if ( $done && is_wp_error( Reviewed_Store::wp_update_post( wp_slash( $update ), true ) ) ) { throw new \RuntimeException( 'media_action_changed' ); } return $done; } finally { Reviewed_Store::leave( $lock ); } } }