0

everyone, I have this code that makes all the files in a folder visible and downloadable on the frontend through a shortcode. But I want to put it in Essential Addons' Advanced Tabs, and they don't quite work together because everytime i search for a file, or I go to page 2, or something else, the page refreshes and I'm no longer on the same tab I was. So I figured my solution would be to prevent the page from refreshing when interacting with the code's interface. I tried using AJAX, but my poor skills almost destroyed my connection to the website (403 everywhere). Mind you, I'm a VERY amateur programmer, and I made the current code with the help of AI. I turn to you guys, I hope I described the problem properly. If you guys are able to help me, I will be eternally grateful. Code below:

function list_files_shortcode($atts) {
    // Set default attributes
    $atts = shortcode_atts(
        array(
            'folder' => '', // Replace with your default path
        ),
        $atts,
        'list_files'
    );

    // Get the absolute path of the folder on the server
    $absolute_folder_path = ABSPATH . $atts['folder'];

    // Check if the folder exists
    if (!is_dir($absolute_folder_path)) {
        return 'The folder does not exist.';
    }

    // Get the name of the current folder
    $current_folder_name = basename($absolute_folder_path);

    // Get the name of the parent folder
    $parent_folder_name = basename(dirname($absolute_folder_path));

    // Check if there is a search term
    $search_term = isset($_GET['search_term']) ? sanitize_text_field($_GET['search_term']) : '';

    // Get the list of files in the folder
    $files = scandir($absolute_folder_path);

    // Filter files based on the search term and exclude "." and ".."
    $filtered_files = array_filter($files, function ($file) use ($search_term) {
        return $file != "." && $file != ".." && (empty($search_term) || stripos($file, $search_term) !== false);
    });

    // Calculate the total number of files
    $total_files = count($filtered_files);

    // Set the number of files per page
    $files_per_page = 10;

    // Calculate the total number of pages
    $total_pages = ceil($total_files / $files_per_page);

    // Get the current page number from the 'page' parameter
    $current_page = isset($_GET['page']) ? max(1, intval($_GET['page'])) : 1;

    // Calculate the starting index of the array for the current page
    $start_index = ($current_page - 1) * $files_per_page;

    // Get the files for the current page
    $files_current_page = array_slice($filtered_files, $start_index, $files_per_page);

    // Start the HTML output
    $output = '';

    // Add folder names above the search bar
    $output .= '<p class="folder-name" style="padding: 10px; border: 1px solid #ccc;">Current Folder Name: ' . $current_folder_name . '</p>';
    $output .= '<p class="folder-name" style="padding: 10px; border: 1px solid #ccc;">Parent Folder Name: ' . $parent_folder_name . '</p>';

    // Add search box, search button, and clear search button with styles
    $output .= '<form action="" method="get" style="margin-top: 20px; padding: 10px; border: 1px solid #ccc;">';
    $output .= '<div style="display: flex; align-items: center;">';
    $output .= '<input type="text" name="search_term" placeholder="Enter file name" value="' . esc_attr(isset($_GET['search_term']) ? $_GET['search_term'] : '') . '" style="flex: 1; padding: 8px; border: 1px solid #ccc;">';
    $output .= '<input type="hidden" name="folder" value="' . esc_attr($atts['folder']) . '">';
    $output .= '<input type="submit" value="Search" style="margin-left: 10px; padding: 8px; border: 1px solid #ccc;">';
    
    // Add the Clear Search button
    if (isset($_GET['search_term']) && !empty($_GET['search_term'])) {
        $output .= '<input type="button" value="Clear Search" onclick="location.href=\'' . esc_url(remove_query_arg('search_term')) . '\'">';
    }

    $output .= '</div>';
    $output .= '</form>';

    // Start the HTML output for the list of files
    $output .= '<ul class="files-list">';

    // Loop through the files of the current page
    foreach ($files_current_page as $file) {
        // Build the complete URL for the file
        $file_url = site_url($atts['folder'] . '/' . $file);

        // Add a list item for each matching file
        $output .= '<li><i class="fas fa-file"></i><a href="' . esc_url($file_url) . '">' . $file . '</a></li>';
    }

    // Close the list
    $output .= '</ul>';

    // Add page navigation
    if ($total_pages > 1) {
        $output .= '<div class="pagination">';
        for ($i = 1; $i <= $total_pages; $i++) {
            $output .= '<a href="' . esc_url(add_query_arg('page', $i)) . '" ' . ($i == $current_page ? 'class="current-page"' : '') . '>' . $i . '</a>';
        }
        $output .= '</div>';
    }

    // Add a message if no files are found
    if (empty($files_current_page) && !empty($search_term)) {
        $output .= '<p>No files found.</p>';
    }

    // Return the generated output
    return $output;
}

// Register the shortcode
add_shortcode('list_files', 'list_files_shortcode');

Thank you all.

UPDATE: This is the code I used to try and implement AJAX:

// Add necessary scripts and styles
function list_files_scripts() {
    wp_enqueue_script('ajax-script', get_template_directory_uri() . '/js/ajax-script.js', array('jquery'), '1.0', true);
    wp_localize_script('ajax-script', 'ajax_object', array('ajax_url' => admin_url('admin-ajax.php')));
}

add_action('wp_enqueue_scripts', 'list_files_scripts');

// Function to list files
function list_files_shortcode($atts) {
    $atts = shortcode_atts(
        array(
            'folder' => 'wp-content/uploads/2023/11',
        ),
        $atts,
        'list_files'
    );

    $output = '';

    $output .= '<p class="folder-name" style="font-size: 18px; font-weight: bold;">Current Folder Name: ' . basename(ABSPATH . $atts['folder']) . '</p>';
    $output .= '<p class="folder-name" style="font-size: 18px; font-weight: bold;">Parent Folder Name: ' . basename(dirname(ABSPATH . $atts['folder'])) . '</p>';

    $output .= '<form action="" method="post" class="list-files-form" style="margin-top: 20px; padding: 10px; border: 1px solid #ccc;">';
    $output .= '<div style="display: flex; align-items: center;">';
    $output .= '<input type="hidden" name="action" value="list_files_ajax">';
    $output .= '<input type="hidden" name="folder" value="' . esc_attr($atts['folder']) . '">';
    $output .= '<input type="text" name="search_term" placeholder="Enter file name" value="' . esc_attr(isset($_POST['search_term']) ? $_POST['search_term'] : '') . '" style="flex: 1; padding: 8px; border: 1px solid #ccc;">';
    $output .= '<input type="submit" value="Search" style="margin-left: 10px; padding: 8px; border: 1px solid #ccc;">';

    if (isset($_POST['search_term']) && !empty($_POST['search_term'])) {
        $output .= '<input type="button" value="Clear Search" onclick="location.href=\'' . esc_url(remove_query_arg('search_term')) . '\'">';
    }

    $output .= '</div>';
    $output .= '</form>';

    $output .= '<div class="files-list"></div>';

    return $output;
}

add_shortcode('list_files', 'list_files_shortcode');

// Function to process AJAX request
add_action('wp_ajax_list_files_ajax', 'list_files_ajax_callback');
add_action('wp_ajax_nopriv_list_files_ajax', 'list_files_ajax_callback');

function list_files_ajax_callback() {
    $folder = isset($_POST['folder']) ? sanitize_text_field($_POST['folder']) : '';
    $search_term = isset($_POST['search_term']) ? sanitize_text_field($_POST['search_term']) : '';

    // Get the list of files with the helper function
    $files = get_files_list($folder, $search_term);

    // Output the list of files (HTML)
    echo '<ul class="files-list">';
    foreach ($files as $file) {
        $file_url = site_url($folder . '/' . $file);
        echo '<li><i class="fas fa-file"></i><a href="' . esc_url($file_url) . '">' . $file . '</a></li>';
    }
    echo '</ul>';

    wp_die(); // Important to terminate execution after AJAX output
}

// Helper function to get the list of files
function get_files_list($folder, $search_term) {
    $absolute_folder_path = ABSPATH . $folder;

    if (!is_dir($absolute_folder_path)) {
        return array();
    }

    $files = scandir($absolute_folder_path);

    $filtered_files = array_filter($files, function ($file) use ($search_term) {
        return $file != "." && $file != ".." && (empty($search_term) || stripos($file, $search_term) !== false);
    });

    return $filtered_files;
}

Then I created an AJAX script in my theme's folder (theme folder/js/ajax-script.js):

jQuery(document).ready(function ($) {
    // Intercept form submission
    $('form').submit(function () {
        var form = $(this);

        // Make an AJAX request
        $.ajax({
            type: form.attr('method'),
            url: form.attr('action'),
            data: form.serialize(),
            success: function (response) {
                // Update the list of files without reloading the page
                $('.files-list').html(response);
            }
        });

        // Prevent the default form submission
        return false;
    });
});
4
  • you mentioned you tried to use AJAX but I can't see any AJAX/REST API handlers or javascript to make requests and process them. Is there code missing from your question?
    – Tom J Nowell
    Commented Jan 10 at 17:40
  • @TomJNowell I did use a different code, but since it was breaking my connection, I discarded it. I will update the post with the code I used.
    – Maellion
    Commented Jan 10 at 19:36
  • the Essential Addons' Advanced Tabs plugin, when stuff is on the second tab and you're looking at the first tab, is the second tab hidden with CSS? Or is it removed and swapped out? If it's the second then that will be a major problem. Does your code work if you remove the tabs? Try to isolate the problem and remove as many things as you can till you get to the simplest most straight forward version and it will be much easier to fix. Then you can add things back in until you're where you want
    – Tom J Nowell
    Commented Jan 11 at 11:36
  • from looking at the JQuery code you wrote, it's submitting the form and putting the response in a particular place, but it's putting the full entire HTML page, not just the files list
    – Tom J Nowell
    Commented Jan 11 at 11:37

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.