uploads = $uploads; } /** * Registers the hooks. */ public function register_hooks() { add_action( 'add_meta_boxes_' . Post_Types::REQUEST, array( $this, 'add_boxes' ) ); add_action( 'save_post_' . Post_Types::REQUEST, array( $this, 'save' ) ); add_action( 'admin_post_' . self::PHOTO_ACTION, array( $this, 'serve_photo' ) ); } /** * Adds the boxes. */ public function add_boxes() { add_meta_box( 'primiko-request', __( 'Request', 'primiko' ), array( $this, 'render' ), Post_Types::REQUEST, 'normal', 'high' ); add_meta_box( 'primiko-request-status', __( 'Status', 'primiko' ), array( $this, 'render_status' ), Post_Types::REQUEST, 'side', 'high' ); } /** * Prints the answers and the photos. * * @param \WP_Post $post Request post. */ public function render( $post ) { $email = (string) get_post_meta( $post->ID, '_primiko_email', true ); $photos = (array) get_post_meta( $post->ID, '_primiko_photos', true ); $trade = (string) get_post_meta( $post->ID, '_primiko_trade', true ); $form = get_post( (int) $post->post_parent ); $single = (bool) get_post_meta( $post->ID, '_primiko_single', true ); // The name the business gave its form says more than the template name. if ( $form && Post_Types::FORM === $form->post_type && '' !== $form->post_title ) { $trade = $form->post_title; } $reply = $single /* translators: %s: site name. */ ? __( 'Your message to %s', 'primiko' ) /* translators: %s: site name. */ : __( 'Your quote request to %s', 'primiko' ); ?>
ID, '_primiko_entries', true ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Escaped in Entries::html(). ?> ID, '_primiko_status', true ); wp_nonce_field( self::NONCE, self::NONCE ); ?> self::PHOTO_ACTION, 'request' => $request_id, 'photo' => $index, ), admin_url( 'admin-post.php' ) ), self::PHOTO_ACTION . '_' . $request_id ); } /** * Sends a photo to a user allowed to edit its request. */ public function serve_photo() { $request_id = isset( $_GET['request'] ) ? absint( $_GET['request'] ) : 0; $index = isset( $_GET['photo'] ) ? absint( $_GET['photo'] ) : 0; check_admin_referer( self::PHOTO_ACTION . '_' . $request_id ); if ( Post_Types::REQUEST !== get_post_type( $request_id ) || ! current_user_can( 'edit_post', $request_id ) ) { wp_die( esc_html__( 'You are not allowed to see this photo.', 'primiko' ), '', array( 'response' => 403 ) ); } $photos = (array) get_post_meta( $request_id, '_primiko_photos', true ); $path = isset( $photos[ $index ] ) ? $this->uploads->path( (string) $photos[ $index ] ) : ''; $type = '' !== $path ? wp_check_filetype( $path ) : array( 'type' => false ); if ( '' === $path || ! in_array( $type['type'], array( 'image/jpeg', 'image/png', 'image/webp' ), true ) ) { wp_die( esc_html__( 'This photo cannot be found.', 'primiko' ), '', array( 'response' => 404 ) ); } nocache_headers(); header( 'Content-Type: ' . $type['type'] ); header( 'Content-Length: ' . filesize( $path ) ); header( 'X-Content-Type-Options: nosniff' ); header( "Content-Security-Policy: default-src 'none'; img-src 'self'; sandbox" ); header( 'Cross-Origin-Resource-Policy: same-origin' ); header( 'Content-Disposition: inline; filename="' . basename( $path ) . '"' ); readfile( $path ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_readfile -- Streams a private image to an authorized user. exit; } }