Accessing a random image via ajax

The goal with this is to create a random banner, managed in the wp admin. I can create a banner solution in the wp admin without an issue but need a little help on the ajax side.

I have an image http://example.com/wp-content/uploads/2015/12/image-name.jpg

I created a random_banner function in functions.php.

add_action( 'wp_ajax_random_banner', 'random_banner' );
add_action( 'wp_ajax_nopriv_random_banner', 'random_banner' );

function random_banner() {
    $image = file_get_contents( 'http://example.com/wp-content/uploads/2015/12/image-name.jpg' );
    header( 'Content-type: image/jpeg;' );
    header( "Content-Length: " . strlen( $image ) );
    echo $image;
}

BTW I have tested this outside of wp and it works great.

Anyway, I then link to this function in an image src like:

<img src="http://example.com//wp-admin/admin-ajax.php?action=random_banner">

This currently returns a broken image icon in chrome. The permissions on my uploads folder is 775.

Not sure what else to try.

Solutions Collecting From Web of "Accessing a random image via ajax"

There is an error in your src;

<img src="http://example.com//wp-admin/admin-ajax.php?action=random_banner">

Try this one:

<img src="http://example.com/wp-admin/admin-ajax.php?action=random_banner">

or

<img src="<?php echo admin_url( 'admin-ajax.php?action=random_banner' ); ?>">

You can also use a query to get a random image.

AJAX

add_action( 'wp_ajax_random_banner', 'random_banner' );
add_action( 'wp_ajax_nopriv_random_banner', 'random_banner' );

function random_banner() {

    // search for 1 random image

    $image_ids = get_posts(
        array(
            'post_type'      => 'attachment',
            'post_mime_type' => 'image',
            'post_status'    => 'inherit',
            'numberposts'    => 1,
            'orderby'        => 'rand',
            'fields'         => 'ids',
        ) );

    // convert id to url

    $images = array_map( "wp_get_attachment_url", $image_ids );

    $image_id = $image_ids[ 0 ];
    $image_url = $images[0];

    // make sure path is readable -- if not, stop!

    // this won't work with URL :(
    // if( !is_readable($image_url)) {
    //    wp_die( "File is not readable: $image_url" );
    // }

    $image    = file_get_contents( $image_url );
    $type     = get_post_mime_type( $image_id );
    if ( empty ( $type ) ) {
        $type = "image/jpg";
    }

    // output headers and image data

    nocache_headers();
    header( "Content-type: $type;" );
    header( "Content-Length: " . strlen( $image ) );

    echo $image;
    die();
}

Update | Endpoint Alternate

Skip the AJAX call and just create an API endpoint for your random image function using add_rewrite_rule().

IMAGE

<img src="http://example.com/api/images/random">

PHP

/**
 * Creates endpoint to select random image from Library
 *
 * http://example.com/api/images/random
 *
 */
if ( ! class_exists( 'Endpoint_RandomImage' ) ):
    /**
     * The code that registers the endpoint and handles the result
     */
    class Endpoint_RandomImage {

        const ENDPOINT_NAME       = 'api/images/random'; // endpoint to capture
        const ENDPOINT_QUERY_NAME = '__api_images_random'; // turns to param

        // WordPress hooks
        public function run() {
            add_filter( 'query_vars', array( $this, 'add_query_vars' ), 0 );
            add_action( 'parse_request', array( $this, 'sniff_requests' ), 0 );
            add_action( 'init', array( $this, 'add_endpoint' ), 0 );
        }

        // Add public query vars
        public function add_query_vars( $vars ) {
            $vars[] = static::ENDPOINT_QUERY_NAME;
            $vars[] = 'extra';

            return $vars;
        }

        // Add API Endpoint
        public function add_endpoint() {
            add_rewrite_rule( '^' . static::ENDPOINT_NAME . '?$', 'index.php?' . static::ENDPOINT_QUERY_NAME . '=1', 'top' );
            add_rewrite_rule( '^' . static::ENDPOINT_NAME . '/([^/]+)/?$', 'index.php?' . static::ENDPOINT_QUERY_NAME . '=1&extra=$matches[1]', 'top' );
// --->
            flush_rewrite_rules( true ); //// <---------- REMOVE THIS WHEN DONE TESTING
// --->
        }

        // Sniff Requests
        public function sniff_requests( $wp_query ) {

            global $wp;

            if ( isset( $wp->query_vars[ static::ENDPOINT_QUERY_NAME ] ) ) {
                $this->handle_request(); // handle it
            }
        }

        // Handle Requests
        protected function handle_request() {
            global $wp;

            $image_ids = get_posts(
                array(
                    'post_type'      => 'attachment',
                    'post_mime_type' => 'image',
                    'post_status'    => 'inherit',
                    'numberposts'    => 1,
                    'orderby'        => 'rand',
                    'fields'         => 'ids',
                ) );

            // convert ids to urls
            // $images = array_map( "wp_get_attachment_url", $image_ids );

            // convert ids to paths
            $images = array_map( "get_attached_file", $image_ids );

            $image_id   = $image_ids[ 0 ];
            $image_path = $images[ 0 ];

            // make sure url is readable -- if not, stop!
            if ( ! is_readable( $image_path ) ) {
                wp_die( "File is not readable: $image_path" );
            }

            $image = file_get_contents( $image_path );
            $type  = get_post_mime_type( $image_id );
            if ( empty ( $type ) ) {
                $type = "image/jpg";
            }

            // output headers and image data

            nocache_headers();
            header( "Content-type: $type;" );
            header( "Content-Length: " . strlen( $image ) );

            echo $image;
            die();
        }
    }

    $ep = new Endpoint_RandomImage();
    $ep->run();

endif; // Endpoint_RandomImage

Endpoint Alternate #2

<img src="http://example.com/api/random-banner/">

Using the rewrites + query tags.

<?php

if ( ! class_exists( 'Prefix_API' ) ) {

    class Prefix_API {

        function __invoke() {
            add_action( 'init', array ( $this, 'prefix__init' ) );
            add_action( 'pre_get_posts', array ( $this, 'prefix__pre_get_posts' ) );
        }

        /**
         * Register a rewrite endpoint for the API.
         */
        function prefix__init() {
            // add tags with `_` prefix to avoid screwing up query
            add_rewrite_tag( '%_api_action%', '([a-zA-Z\d\-_+]+)' );

            // create URL rewrite
            add_rewrite_rule( '^api/([a-zA-Z\d\-_+]+)/?', 'index.php?_api_action=$matches[1]', 'top' );

            // required once after rules added/changed
            flush_rewrite_rules( true );
        }

        /**
         * Handle data (maybe) passed to the API endpoint.
         *
         * @param $query
         */
        function prefix__pre_get_posts( $query ) {

            if ( isset( $query->query_vars[ '_api_action' ] ) ) {

                switch ( $query->query_vars[ '_api_action' ] ) {
                    case 'random-banner';
                        $this->prefix__show_random_image();
                        break;
                }

                // kill the request on an API action call
                die();
            }
        }

        /**
         * Show random image
         *
         * @see http://example.com/api/random-banner/
         */
        function prefix__show_random_image() {
            $image_ids = get_posts( array (
                'post_type'      => 'attachment',
                'post_mime_type' => 'image',
                'post_status'    => 'inherit',
                'numberposts'    => 1,
                'orderby'        => 'rand',
                'fields'         => 'ids',
            ) );

            // convert ids to urls
            // $images = array_map( "wp_get_attachment_url", $image_ids );

            // convert ids to paths
            $images = array_map( "get_attached_file", $image_ids );

            $image_id   = $image_ids[ 0 ];
            $image_path = $images[ 0 ];

            // make sure url is readable -- if not, stop!
            if ( ! is_readable( $image_path ) ) {
                wp_die( "File is not readable: $image_path" );
            }

            $image = file_get_contents( $image_path );
            $type  = get_post_mime_type( $image_id );
            if ( empty ( $type ) ) {
                $type = "image/jpg";
            }

            // output headers and image data

            nocache_headers();
            header( "Content-type: $type;" );
            header( "Content-Length: " . strlen( $image ) );

            echo $image;
            die();
        }

    }

    // create api instance
    $api = new Prefix_API();

    // initialize the api hooks
    $api();
}

REST API

<img src="http://example.com/wp-json/prefix/v1/random-image/">

This version uses a custom REST API route.

/**
 * Register the REST route.
 * 
 * @see http://example.com/wp-json/prefix/v1/random-image/ 
 */
add_action( 'rest_api_init', function () {
    register_rest_route( 'prefix/v1', '/random-image/', array(
        'methods' => 'GET, POST',
        'callback' => 'prefix__show_random_image',
        'show_in_index' => false,
    ) );
} );

/**
 * Show random image
 */
function prefix__show_random_image(){
    $image_ids = get_posts(
        array(
            'post_type'      => 'attachment',
            'post_mime_type' => 'image',
            'post_status'    => 'inherit',
            'numberposts'    => 1,
            'orderby'        => 'rand',
            'fields'         => 'ids',
        ) );

    // convert ids to urls
    // $images = array_map( "wp_get_attachment_url", $image_ids );

    // convert ids to paths
    $images = array_map( "get_attached_file", $image_ids );

    $image_id   = $image_ids[ 0 ];
    $image_path = $images[ 0 ];

    // make sure url is readable -- if not, stop!
    if ( ! is_readable( $image_path ) ) {
        wp_die( "File is not readable: $image_path" );
    }

    $image = file_get_contents( $image_path );
    $type  = get_post_mime_type( $image_id );
    if ( empty ( $type ) ) {
        $type = "image/jpg";
    }

    // output headers and image data

    nocache_headers();
    header( "Content-type: $type;" );
    header( "Content-Length: " . strlen( $image ) );

    echo $image;
    die();
}