• I really love this plug-in, since I have full control of the gallery wrapper on the front end, and the editing of the images in on the main editing page of the custom post type.

    For anyone else that is like me and does not want to change to something else, feel free to try to this.

    1- Make a back up of your current plug-in files. Open up your local files (multi-image-metabox.php and get-images.js)

    2 – Update your multi-image-metabox.php file to this code (I did not change the version number, but you can make something up if you want).

    <?php
    /*
    Plugin Name: Multi Image Metabox
    Plugin URI: http://wabeo.fr
    Description: Add a multi-image metabox to your posts, pages and custom post types
    Version: 1.3.5
    Author: Willy bahuaud
    Author URI: http://wabeo.fr
    */

    /**
    * 1. GET IMAGE SLOTS CONFIGURATION
    */
    function list_my_images_slots( $cpt = false ){
    $list_images = apply_filters('list_images', array(
    'image1' => '_image1',
    'image2' => '_image2',
    'image3' => '_image3',
    'image4' => '_image4',
    'image5' => '_image5',
    'image6' => '_image6',
    'image7' => '_image7',
    'image8' => '_image8'
    ), $cpt );
    return $list_images;
    }

    /**
    * 2. INITIALIZE METABOX REGISTRATION
    */
    add_action("admin_init", "add_image_metabox");
    function add_image_metabox(){
    $cpts = apply_filters('images_cpt', array('page'));
    foreach($cpts as $cpt) {
    add_meta_box('imagesliees', __('Add Photos'), "imagesliees", $cpt, 'normal', 'core');
    }
    }

    /**
    * 3. SAFE ASSET LOADING ON ADMIN EDIT SCREENS
    */
    add_action( 'admin_enqueue_scripts', 'multi_image_metabox_scripts' );
    function multi_image_metabox_scripts( $hook ) {
    // Only load assets on post editing and post creation layouts
    if ( 'post.php' !== $hook && 'post-new.php' !== $hook ) {
    return;
    }

    // Native WordPress media toolkit
    wp_enqueue_media();

    // Enqueue standard jQuery UI components needed for visual re-sorting
    wp_enqueue_script( 'jquery-ui-sortable' );

    // Enqueue your custom internal plugin file helper
    wp_enqueue_script( 'img-mb', plugins_url('/get-images.js', __FILE__), array( 'jquery', 'jquery-ui-sortable' ), '1.3.5', true );
    }

    /**
    * 4. GENERATE THE METABOX LAYOUT
    */
    function imagesliees($post){
    $list_images = list_my_images_slots();

    // Output security layout verification field
    wp_nonce_field( 'image-liee-save_'.$post->ID, 'image-liee-nonce');

    echo '<div id="droppable">';
    $z = 1;

    foreach($list_images as $k => $i){
    $meta = get_post_meta($post->ID, $i, true);

    // Confirm the asset ID is a valid number before rendering image tag
    $img = '';
    if ( ! empty( $meta ) && is_numeric( $meta ) ) {
    $thumb_url = wp_get_attachment_thumb_url($meta);
    if ( $thumb_url ) {
    $img = '<img src="' . esc_url($thumb_url) . '" width="100" height="100" alt="" draggable="false">';
    }
    }

    echo '<div class="image-entry">';
    echo '<input type="hidden" name="'.esc_attr($k).'" id="'.esc_attr($k).'" class="id_img" data-num="'.intval($z).'" value="'.esc_attr($meta).'">';
    echo '<div class="img-preview" data-num="'.intval($z).'">'.$img.'</div>';
    echo '<a href="javascript:void(0);" class="get-image button-secondary" data-num="'.intval($z).'">'._x('Add New','file').'</a> ';
    echo '<a href="javascript:void(0);" class="del-image button-secondary" data-num="'.intval($z).'">'.__('Delete').'</a>';
    echo '</div>';

    $z++;
    }
    echo '</div>';
    ?>

    <div style="clear:left;"></div>

    <script>
    jQuery(document).ready(function($){
    // Sequentially adjust hidden metadata names and IDs during layout changes
    function reorderImages(){
    $('#droppable .image-entry').each(function(i){
    var num = i + 1;
    $(this).find('.get-image').attr('data-num', num);
    $(this).find('.del-image').attr('data-num', num);
    $(this).find('div.img-preview').attr('data-num', num);

    var $input = $(this).find('input.id_img');
    $input.attr('name', 'image' + num)
    .attr('id', 'image' + num)
    .attr('data-num', num);
    });
    }

    // Activate native, stable jQuery UI interface engine
    if ( $.isFunction($.fn.sortable) ) {
    $( "#droppable" ).sortable({
    opacity: 0.6,
    cursor: 'move',
    items: '.image-entry',
    placeholder: 'image-entry-placeholder',
    update: function(event, ui) {
    reorderImages();
    }
    });
    }
    });
    </script>

    <style type="text/css">
    .img-preview {
    position: relative;
    display: block;
    width: 100px;
    height: 100px;
    background: #efefef;
    border: 1px solid #FFF;
    }
    .img-preview img {
    position: absolute;
    top: 0;
    left: 0;
    }
    .image-entry {
    float: left;
    margin: 0 10px 10px 0;
    border: 2px solid #ccc;
    padding: 10px;
    background: #FFF;
    cursor: move;
    }
    .image-entry:last-child {
    margin-right: 0;
    }
    .image-entry-placeholder {
    float: left;
    margin: 0 10px 10px 0;
    border: 2px dashed #999;
    padding: 10px;
    background: #f9f9f9;
    width: 100px;
    height: 140px;
    }
    .get-image, .del-image {
    margin-top: 10px !important;
    display: block !important;
    text-align: center;
    }
    </style>
    <?php
    }

    /**
    * 5. SAVE METABOX DATA SAFELY
    */
    add_action('save_post', 'save_image_metabox');
    function save_image_metabox($post_ID){
    // Bail if this is an automatic background save
    if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) {
    return $post_ID;
    }

    // Validate system authorization token
    if ( isset($_POST['image-liee-nonce']) && isset($_POST['post_ID']) ) {
    check_admin_referer('image-liee-save_' . $_POST['post_ID'], 'image-liee-nonce');
    } else {
    return $post_ID;
    }

    $list_images = list_my_images_slots();
    foreach($list_images as $k => $i){
    if ( isset( $_POST[$k] ) ) {
    update_post_meta($post_ID, $i, sanitize_text_field($_POST[$k]));
    } else {
    delete_post_meta($post_ID, $i);
    }
    }
    }

    3 – Update your get-images.js to this:

    jQuery(document).ready(function($) {

    var formfield = null, formfielddeux = null, num ='';

    // 1. Media selector launcher
    $('.get-image').on( 'click', function() {
    $('html').addClass('image_spe');
    num = $(this).attr('data-num');
    formfield = $('.id_img[data-num="'+num+'"]').attr('name');
    var id = $("#post_ID").val();
    tb_show('', 'media-upload.php?post_id='+id+'&type=image&TB_iframe=true');
    return false;
    });

    // 2. Delete button logic
    $('.del-image').on('click', function(){
    var cible = $(this).attr('data-num');
    $('.img-preview[data-num="'+cible+'"]').empty();
    $('.id_img[data-num="'+cible+'"]').val('');
    });

    // FIXED: Changed old '.live()' method to modern delegated '.on()' event handler
    $(document).on('click', '.upload_pdf_button', function() {
    $('html').addClass('pdf');
    num = $(this).attr('data-cible');
    formfielddeux = $('.url_pdf_input[data-input="'+num+'"]').attr('name');
    var id = $("#post_ID").val();
    tb_show('', 'media-upload.php?post_id='+id+'&type=file&TB_iframe=true');
    return false;
    });

    // 3. Intercept media submission framework
    window.original_send_to_editor = window.send_to_editor;
    window.send_to_editor = function(html){
    var fileurl;

    if (formfield !== null) {
    var matches = html.match(/wp-image-([0-9]*)/);

    // FIXED: Added security condition to prevent errors if regex doesn't match an image ID
    if (matches && matches[1]) {
    $('input[name="'+formfield+'"]').val(matches[1]);
    }

    // Cleanly empty the previous container preview element before adding a new one
    var $preview = $('.img-preview[data-num="'+num+'"]').empty();

    // Extract image element source cleanly
    var img_tag = $(html).find('img').length ? $(html).find('img') : $(html).filter('img');

    if (img_tag.length) {
    img_tag.attr('width', '100').attr('height', '100').css({width: "100px", height: "100px"});
    $preview.append(img_tag);
    }

    tb_remove();
    $('html').removeClass('image_spe');
    formfield = null;
    num = null;

    } else {
    if (formfielddeux !== null) {
    fileurl = $(html).filter('a').attr('href');
    if (!fileurl) {
    fileurl = $(html).find('a').attr('href');
    }

    $('.url_pdf_input[data-input="'+num+'"]').val(fileurl);
    tb_remove();
    $('html').removeClass('pdf');
    formfielddeux = null;
    num = null;
    } else {
    window.original_send_to_editor(html);
    }
    }
    };
    });

    4 – Upload the 2 files to your server via FTP or File Manager.

    It works for me. I haven’t been able to add new entries to my projects custom post type for some years with the newer versions of WordPress, but now I can.

    Hopefully it helps your custom themes to keep running alone. 🙂

Viewing 1 replies (of 1 total)
  • Thread Starter ellice909

    (@ellice909)

    Update – This JS uses the modern WP file browser. The above code uses the legacy one. The legacy one was working on my dev site, but not my live site, so I switched to the new one:

    jQuery(document).ready(function($) {

    var file_frame;
    var num = '';

    // 1. Modernized Image Uploader Engine (Replaces old tb_show iframe)
    $('.get-image').on('click', function(event) {
    event.preventDefault();

    num = $(this).attr('data-num');

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

    // Create the media frame.
    file_frame = wp.media.frames.file_frame = wp.media({
    title: 'Select or Upload an Image',
    button: {
    text: 'Use this image'
    },
    multiple: false // Set to true if you want multiple file selection
    });

    // When an image is selected, run a callback.
    file_frame.on('select', function() {
    // We turn the selection into an attachment object
    var attachment = file_frame.state().get('selection').first().toJSON();

    // Assign the numeric Attachment ID to our hidden input field
    $('.id_img[data-num="' + num + '"]').val(attachment.id);

    // Clean up previous thumb previews and generate the new container view
    var $preview = $('.img-preview[data-num="' + num + '"]').empty();

    // Use the thumbnail size or fallback to full if thumb is unavailable
    var thumbUrl = attachment.sizes.thumbnail ? attachment.sizes.thumbnail.url : attachment.url;

    var img_tag = $('<img>', {
    src: thumbUrl,
    width: 100,
    height: 100,
    style: 'width:100px; height:100px;'
    });

    $preview.append(img_tag);

    num = null;
    });

    // Finally, open the modal frame window
    file_frame.open();
    });

    // 2. Clear out fields on Delete action clicks
    $('.del-image').on('click', function(){
    var cible = $(this).attr('data-num');
    $('.img-preview[data-num="'+cible+'"]').empty();
    $('.id_img[data-num="'+cible+'"]').val('');
    });

    // 3. Modernized PDF/File Selector Engine (No iframe fallback crash)
    var pdf_frame;
    $(document).on('click', '.upload_pdf_button', function(event) {
    event.preventDefault();

    var num_pdf = $(this).attr('data-cible');

    if (pdf_frame) {
    pdf_frame.open();
    return;
    }

    pdf_frame = wp.media.frames.pdf_frame = wp.media({
    title: 'Select or Upload a PDF Document',
    button: {
    text: 'Use this document'
    },
    library: {
    type: 'application/pdf' // Restricts options purely to PDFs
    },
    multiple: false
    });

    pdf_frame.on('select', function() {
    var attachment = pdf_frame.state().get('selection').first().toJSON();
    $('.url_pdf_input[data-input="' + num_pdf + '"]').val(attachment.url);
    });

    pdf_frame.open();
    });

    });
Viewing 1 replies (of 1 total)

You must be logged in to reply to this topic.