Ongebruikte Media Opsporings Tool

Met deze gratis tool voeg je een extra menu-optie toe in je WordPress-dashboard (Media → Ongebruikte Media).
Daar zie je meteen welke afbeeldingen in je mediabibliotheek niet meer gebruikt worden op de frontend van je site.

Zolang je de snippet geactiveerd laat via een plugin als WPCode of Code Snippets, blijft deze optie beschikbaar en kun je wanneer je wilt je mediabibliotheek opschonen. Wanneer je klaar bent kun je simpelweg de snippet weer deactiveren.


🔎 Wat doet deze tool?

  • Voegt een submenu toe onder Media → Ongebruikte Media.

  • Spoort ongebruikte afbeeldingen op: bestanden die niet voorkomen in pagina’s, berichten, uitgelichte afbeeldingen of algemene instellingen.

  • Geeft inzicht in bestandsnaam, afmetingen (pixels) en bestandsgrootte (MB/KB).

  • Beheer vanuit je dashboard: vink aan wat je wilt verwijderen en gebruik de bulk-delete knop.

  • Selecteer alles: met één klik alles aanvinken.

Waar moet je rekening mee houden?

  1. Maak altijd een backup van je site (bestanden en database) voordat je gaat verwijderen.

  2. Deze tool controleert alleen de standaard database-velden. Afbeeldingen die via page builders of plugins (bijv. Elementor of ACF) geladen worden, kunnen soms als ongebruikt worden aangemerkt. Controleer daarom altijd handmatig.

  3. De lijst is om performance-redenen beperkt tot maximaal 500 afbeeldingen per keer.


📋 Installatie

  1. Kopieer de code hieronder.

  2. Plaats hem in een snippet-plugin (WPCode of Code Snippets).

  3. Zet hem op Run Everywhere en activeer.

  4. In je dashboard verschijnt nu Media → Ongebruikte Media.

⚡ Wanneer draait de code?

  • De code wordt alleen uitgevoerd als jij of een beheerder naar de pagina Media → Ongebruikte Media gaat.

  • Op de voorkant (frontend) van je site draait de snippet helemaal niet.

  • Ook in de rest van je admin (bijv. bij berichten of instellingen) wordt deze code niet aangeroepen.

👉 Dat betekent dat je gewone bezoekers er niets van merken en dat je site niet trager wordt.

PHP code snippet:

				
					// === Ongebruikte Media Opsporings Tool ===
add_action('admin_menu', function () {
    add_media_page(
        'Ongebruikte Media',
        'Ongebruikte Media',
        'manage_options',
        'unused-media',
        'unused_media_page'
    );
});

function unused_media_page() {
    global $wpdb;

    echo '<div class="wrap"><h1>Ongebruikte Media</h1>';
    echo '<p>Overzicht van afbeeldingen die volgens de database niet worden gebruikt in content, uitgelichte afbeeldingen of site-instellingen.</p>';
    echo '<p><strong>LET OP:</strong> Maak altijd eerst een backup voordat je bestanden verwijdert!</p>';

    // Verwijder geselecteerde bestanden
    if (isset($_POST['delete_unused']) && !empty($_POST['unused_ids']) && is_array($_POST['unused_ids'])) {
        check_admin_referer('delete_unused_media');
        $deleted_count = 0;
        foreach ($_POST['unused_ids'] as $id) {
            $id = intval($id);
            if ($id > 0 && wp_delete_attachment($id, true)) {
                $deleted_count++;
            }
        }
        echo '<div class="updated"><p>'.intval($deleted_count).' ongebruikte afbeeldingen verwijderd.</p></div>';
    }

    // Ophalen maximaal 500 afbeeldingen (voor snelheid)
    $attachments = $wpdb->get_results("
        SELECT ID, post_title, guid 
        FROM {$wpdb->posts} 
        WHERE post_type='attachment' 
        AND post_mime_type LIKE 'image/%' 
        ORDER BY post_date DESC
        LIMIT 500
    ");

    $unused = [];
    if ($attachments) {
        foreach ($attachments as $att) {
            $id  = $att->ID;
            $url = $att->guid;
            $file = get_attached_file($id);

            // Check of afbeelding ergens wordt gebruikt
            $in_posts   = $wpdb->get_var($wpdb->prepare(
                "SELECT COUNT(ID) FROM {$wpdb->posts} WHERE post_content LIKE %s LIMIT 1", 
                '%' . $wpdb->esc_like($url) . '%'
            ));
            $in_thumb   = $wpdb->get_var($wpdb->prepare(
                "SELECT COUNT(meta_id) FROM {$wpdb->postmeta} WHERE meta_key='_thumbnail_id' AND meta_value=%d LIMIT 1", 
                $id
            ));
            $in_options = $wpdb->get_var($wpdb->prepare(
                "SELECT COUNT(option_id) FROM {$wpdb->options} WHERE option_value LIKE %s LIMIT 1", 
                '%' . $wpdb->esc_like($url) . '%'
            ));

            if ($in_posts == 0 && $in_thumb == 0 && $in_options == 0) {
                $size_human = '-';
                $dimensions = '';
                if ($file && file_exists($file)) {
                    $size_human = size_format(filesize($file), 2);
                    $img_info   = @getimagesize($file);
                    if ($img_info) {
                        $dimensions = $img_info[0] . '×' . $img_info[1];
                    }
                }

                $unused[] = [
                    'id'    => $id,
                    'title' => $att->post_title,
                    'url'   => $url,
                    'size'  => $size_human,
                    'dim'   => $dimensions
                ];
            }
        }
    }

    // Tabelweergave
    if (empty($unused)) {
        echo '<p><strong>Geen ongebruikte afbeeldingen gevonden.</strong></p>';
    } else {
        echo '<form method="post">';
        wp_nonce_field('delete_unused_media');
        echo '<table class="widefat"><thead>
                <tr>
                  <th><input type="checkbox" id="select-all"></th>
                  <th>Bestand</th>
                  <th>Afmetingen</th>
                  <th>Grootte</th>
                </tr>
              </thead><tbody>';
        foreach ($unused as $img) {
            echo '<tr>';
            echo '<td><input type="checkbox" name="unused_ids[]" value="'.esc_attr($img['id']).'"></td>';
            echo '<td><a target="_blank" href="'.esc_url($img['url']).'">'.esc_html($img['title']).'</a></td>';
            echo '<td>'.esc_html($img['dim']).'</td>';
            echo '<td>'.esc_html($img['size']).'</td>';
            echo '</tr>';
        }
        echo '</tbody></table>';
        echo '<p><input type="submit" name="delete_unused" class="button button-primary" value="Verwijder geselecteerde"></p>';
        echo '</form>';

        // Selecteer alles script
        echo '<script type="litespeed/javascript">document.getElementById("select-all").addEventListener("click",function(e){var checkboxes=document.querySelectorAll("input[name=\'unused_ids[]\']");for(var i=0;i<checkboxes.length;i++){checkboxes[i].checked=e.target.checked}})</script>';
    }

    echo '</div>';
}