3

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?

  • Just FYI, you could have used events : { 'change:custom_data' 'refresh' } as well to add the event handler. That's how it's normally done in Backbone so you can chain events like 'change:foo click touch' : 'callback'. – kaiser Sep 14 '15 at 23:46
6

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 );

}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.