Switch to the library tab in the media uploader

I’m developing a plugin that adds a tab to the media uploader to add external videos to the media library via oembed. Everything works as expected but I need to switch to the library tab after adding a new external video via the new tab. This is part of the code I’m using:

wp.media.controller.Custom = wp.media.controller.State.extend({

    initialize: function(){
        this.props = new Backbone.Model({ custom_data: '' });
        this.props.on( 'change:custom_data', this.refresh, this );
    },

    refresh: function() {
        this.frame.toolbar.get().refresh();
    },

    customAction: function(){
        wp.media.post( 'add-oembed', {
            url:     this.props.get('custom_data'),
            post_id: wp.media.view.settings.post.id
        });

        this.frame.content.mode('browse');

    }

});

The line this.frame.content.mode('browse') is supposed to make the switch to the library tab, but I’m getting an error message that says:

TypeError: this.collection is undefined

Any ideas?

1 Answer
1

After struggling around for days through the poorly documented media modal source code and using code from the gist (thanks, Fabien), I came up with a solution:

JS:

wp.media.controller.Custom = wp.media.controller.State.extend({

    initialize: function(){
        this.props = new Backbone.Model({ custom_data: '' });
        this.props.on( 'change:custom_data', this.refresh, this );
    },

    refresh: function() {
        this.frame.toolbar.get().refresh();
    },

    // called when the toolbar button is clicked
    customAction: function( controller ){
        // call the PHP function that inserts an oembed attachment to the database via AJAX
        wp.media.post( 'add-oembed', {
            url:     this.props.get( 'custom_data' ),
            post_id: wp.media.view.settings.post.id
        }).done( function( resp ) {
            // create an attachment model using the data from the AJAX response
            var attachment = wp.media.model.Attachment.create( resp );
            var edit = controller.state( 'insert' );
            // add the attachment to the library model
            edit.get( 'library' ).add( attachment );
        });

    }

});


wp.media.view.Toolbar.Custom = wp.media.view.Toolbar.extend({
    initialize: function() {
        _.defaults( this.options, {
            event: 'custom_event',
            close: false,
            items: {
                custom_event: {
                    text: wp.media.view.l10n.customButton,
                    style: 'primary',
                    priority: 80,
                    requires: false,
                    click: this.customAction
                }
            }
        });

        wp.media.view.Toolbar.prototype.initialize.apply( this, arguments );
    },

    refresh: function() {
        var custom_data = this.controller.state().props.get('custom_data');
        this.get('custom_event').model.set( 'disabled', ! custom_data );
        wp.media.view.Toolbar.prototype.refresh.apply( this, arguments );
    },

    // triggered when the button is clicked
    customAction: function(){
        this.controller.state().customAction( this.controller );
        // switch to the library view
        this.controller.setState( 'insert' );
    }

});      

PHP:

add_action('wp_ajax_add-oembed', 'custom_add_oembed');

function custom_add_oembed() {
    $url = $_POST['url'];
    $post_ID = intval($_POST['post_id']);

    if (!current_user_can( 'edit_post', $post_ID ) ) {
        wp_send_json_error();
    }

    $oembed = new WP_oEmbed();
    $provider = $oembed->discover($url);
    if($provider === false && substr($url, 0, 5) === 'https') {
        $url = str_replace('https', 'http', $url);
        $provider = $oembed->discover($url);
    }
    if($provider === false) {
        wp_send_json_error();
    }

    $response = $oembed->fetch($provider, $url);
    if( $response === false) {
        wp_send_json_error();
    }

    $my_post = array(
        'post_parent'   => $post_ID,
        'post_title'    => $response->title,
        'post_content'  => '',
        'post_status'   => 'inherit',
        'post_author'   => get_current_user_id(),
        'post_type'     => 'attachment',
        'guid'          => $url,
        'post_mime_type'=> 'oembed/' . $response->provider_name
    );
    $attachment_id = wp_insert_post( $my_post );
    if( ! is_int($attachment_id) ) {
        wp_send_json_error();
    }

    if ( ! $attachment = wp_prepare_attachment_for_js( $attachment_id ) ) {
        wp_send_json_error();
    }

    wp_send_json_success( $attachment );

}

Leave a Comment