Viết chức năng upload media trong WordPress

Cập nhật lần cuối vào

Bài viết này mình sẽ hướng dẫn cho các bạn cách viết chức năng upload hình ảnh và tập tin trong WordPress, kể từ phiên bản WordPress 3.5 trở về sau thì bạn có thể dùng WordPress Media API để thao tác tải tập tin từ máy tính lên trình quản lý media của WordPress. Cách thực hiện cũng không mấy phức tạp, quan trọng là bạn phải biết cách để viết nó thành một hàm chức năng để dùng lại sau này.

Upload và quản lý media trong WordPress

WordPress Media API là công cụ cho phép bạn dùng code PHP, HTML và Javascript để thực hiện thao tác upload tập tin lên blog. Do vậy, bạn cần phải hiểu được các kiến thức cơ bản trước khi tham gia tìm hiểu trong bài viết này. Trường hợp ngoại lệ, bạn cũng có thể cóp dán để code hoạt động mà không cần quan tâm tới nó hoạt động như thế nào.

<?php
global $post;

// Get WordPress' media upload URL
$upload_link = esc_url( get_upload_iframe_src( 'image', $post->ID ) );

// See if there's a media id already saved as post meta
$your_img_id = get_post_meta( $post->ID, '_your_img_id', true );

// Get the image src
$your_img_src = wp_get_attachment_image_src( $your_img_id, 'full' );

// For convenience, see if the array is valid
$you_have_img = is_array( $your_img_src );
?>

<!-- Your image container, which can be manipulated with js -->
<div class="custom-img-container">
	<?php if ( $you_have_img ) : ?>
		<img src="<?php echo $your_img_src[0] ?>" alt="" style="max-width:100%;" />
	<?php endif; ?>
</div>

<!-- Your add & remove image links -->
<p class="hide-if-no-js">
	<a class="upload-custom-img <?php if ( $you_have_img  ) { echo 'hidden'; } ?>" href="<?php echo $upload_link ?>">
		<?php _e('Set custom image') ?>
	</a>
	<a class="delete-custom-img <?php if ( ! $you_have_img  ) { echo 'hidden'; } ?>" href="#">
		<?php _e('Remove this image'); ?>
	</a>
</p>

<!-- A hidden input to set and post the chosen image id -->
<input class="custom-img-id" name="custom-img-id" type="hidden" value="<?php echo esc_attr( $your_img_id ); ?>" />

Với đoạn code bên trên, bạn sẽ triển khai được các thuộc tính HTML phục vụ cho thao tác upload tập tin, lưu trữ thông tin vào cơ sở dữ liệu. Công việc bạn cần làm tiếp theo đó là soạn code Javascript để thực thi các công việc này.

(function($){

    // Set all variables to be used in scope
    var frame,
        metaBox = $('#meta-box-id.postbox'), // Your meta box id here
        addImgLink = metaBox.find('.upload-custom-img'),
        delImgLink = metaBox.find( '.delete-custom-img'),
        imgContainer = metaBox.find( '.custom-img-container'),
        imgIdInput = metaBox.find( '.custom-img-id' );

    // ADD IMAGE LINK
    addImgLink.on( 'click', function( event ){

        event.preventDefault();

        // If the media frame already exists, reopen it.
        if ( frame ) {
            frame.open();
            return;
        }

        // Create a new media frame
        frame = wp.media({
            title: 'Select or Upload Media Of Your Chosen Persuasion',
            button: {
                text: 'Use this media'
            },
            multiple: false  // Set to true to allow multiple files to be selected
        });


        // When an image is selected in the media frame...
        frame.on( 'select', function() {

            // Get media attachment details from the frame state
            var attachment = frame.state().get('selection').first().toJSON();

            // Send the attachment URL to our custom image input field.
            imgContainer.append( '<img src="'+attachment.url+'" alt="" style="max-width:100%;"/>' );

            // Send the attachment id to our hidden input
            imgIdInput.val( attachment.id );

            // Hide the add image link
            addImgLink.addClass( 'hidden' );

            // Unhide the remove image link
            delImgLink.removeClass( 'hidden' );
        });

        // Finally, open the modal on click
        frame.open();
    });


    // DELETE IMAGE LINK
    delImgLink.on( 'click', function( event ){

        event.preventDefault();

        // Clear out the preview image
        imgContainer.html( '' );

        // Un-hide the add image link
        addImgLink.removeClass( 'hidden' );

        // Hide the delete image link
        delImgLink.addClass( 'hidden' );

        // Delete the image id from the hidden input
        imgIdInput.val( '' );

    });

})(jQuery);

Với những thao tác như bên trên thì bạn đã có thể dùng được chức năng đăng tải tập tin lên media của WordPress. Các hàm này sẽ hữu ích cho bạn khi bạn muốn tạo Meta Box cho bài viết hoặc thêm thông tin tùy chọn nào đấy cho phép người dùng đăng tải tập tin đính kèm vào bài viết.

(function($) {
    function MediaUpload(element, options) {
        this.self = this;
        this.element = element;
        this.options = $.extend({}, MediaUpload.DEFAULTS, options);
        this.items = null;
        this.$element = $(element);
        this.$container = this.$element.parent();
        this.$id = this.$container.find('input.media-id');
        this.$url = this.$container.find('input.media-url');
        this.$preview = this.$container.find('.media-preview');
        this.$remove = this.$container.find('.btn-remove');
        this.$th = this.$container.prev();
        this.$label = this.$th.find('label');
        this._defaults = MediaUpload.DEFAULTS;
        this._name = MediaUpload.NAME;
        this.frame = null;

        this.init();

        this.$element.on('click', $.proxy(this.add, this));
        this.$url.on('change input', $.proxy(this.change, this));
        this.$remove.on('click', $.proxy(this.remove, this));
    }

    MediaUpload.NAME = 'hocwp.mediaUpload';

    MediaUpload.DEFAULTS = {
        title: hocwp.i18n.insert_media_title,
        button_text: null,
        multiple: false
    }

    MediaUpload.prototype.init = function() {
        if(!this.options.button_text) {
            if(this.options.multiple) {
                this.options.button_text = hocwp.i18n.insert_media_button_texts;
            } else {
                this.options.button_text = hocwp.i18n.insert_media_button_text;
            }
        }
    }

    MediaUpload.prototype.selected = function() {
        this.items = hocwp.receiveSelectedMediaItems(this.frame);
        if(!this.options.multiple) {
            var media_item = hocwp.getFirstMediaItemJSON(this.items);
            if(media_item.id) {
                this.$id.val(media_item.id);
            }
            if(media_item.url) {
                this.$url.val(media_item.url);
                this.$preview.html(hocwp.createImageHTML({src: media_item.url}));
                this.$element.addClass('hidden');
                this.$remove.removeClass('hidden');
            }
        }
    }

    MediaUpload.prototype.remove = function(e) {
        e.preventDefault();
        this.$preview.html('');
        this.$url.val('');
        this.$id.val('');
        this.$remove.addClass('hidden');
        this.$element.removeClass('hidden');
    }

    MediaUpload.prototype.add = function(e) {
        e.preventDefault();
        if(this.frame) {
            this.frame.open();
            return;
        }
        this.frame = wp.media({
            title: this.options.title,
            button: {
                text: this.options.button_text
            },
            multiple: this.options.multiple
        });
        this.frame.on('select', $.proxy(this.selected, this));
        this.frame.open();
    }

    MediaUpload.prototype.change = function(e) {
        e.preventDefault();
        if(hocwp.isImageUrl(this.$url.val())) {
            this.$preview.html(hocwp.createImageHTML({src: this.$url.val()}));
        } else {
            this.$preview.html('');
        }
        this.$id.val('');
    }

    $.fn.hocwpMediaUpload = function(options) {
        return this.each(function() {
            if(!$.data(this, MediaUpload.NAME)) {
                $.data(this, MediaUpload.NAME, new MediaUpload(this, options));
            }
        });
    }

})(jQuery);

(function($) {
    (function() {
        $('.btn-insert-media').hocwpMediaUpload();
    })();
})(jQuery);

Để rút ngắn được thời gian, bằng cách khai báo một plugin jQuery, sau đó cứ dùng đi dùng lại nhiều lần, như vậy bạn sẽ tiết kiệm được rất nhiều công sức thì bạn có thể áp dụng đoạn code như trên. Chú ý là các đoạn code chỉ mang tính chất tham khảo, bạn hoàn toàn có thể sửa lại và bổ sung thêm nếu muốn, bài hướng dẫn này chỉ một phần nào gợi ý cho bạn cách để viết một hàm sử dụng WordPress Media API đơn giản, phần việc còn lại là ở bạn nhé, chúc bạn thành công.