CSV Download Debugging Tips

User
Assistant
Your PHP script to generate and download a CSV seems to have some logical issues that might be causing the empty CSV file. Let’s debug the potential causes:

### Issues and Fixes:

1. **Query Results:**
Ensure the `$pageposts` query is returning data. You can add a `var_dump($querystr)` and `var_dump($pageposts)` to verify the SQL query and the fetched results:

var_dump($querystr);
   var_dump($pageposts);
   die();

– If `$pageposts` is empty, there may be an issue with the SQL query or database data.

2. **Dynamic SQL Conditions:**
In the `$sqlcon` variable:

AND t.term_id = '{$catex}'

Using `intval()` for `$catex` is good, but avoid directly injecting it into the SQL query. Use `prepare()` to safely handle dynamic data:

$sqlcon = $catex !== -1 
       ? $wpdb->prepare("AND tt.taxonomy = 'category' AND t.term_id = %d", $catex)
       : "AND tt.taxonomy = 'category' AND t.term_id != '65'";

3. **Join Conditions:**
Ensure the `JOIN` conditions in `$sqlj` are correct. If there’s no matching data between the tables, `$pageposts` will be empty.

4. **Post Status and Type:**
Your query is limited to `p.post_type = 'post'` and `p.post_status = 'publish'`. Ensure the posts you're expecting meet these criteria.

5. **Category Fetch:**
The `get_the_category($post->ID)` function might return an empty array if there are no categories. Add a fallback or ensure all posts have categories.

6. **Yoast Meta Description:**
If `_yoast_wpseo_metadesc` is not set for some posts, the `get_post_meta()` function will return an empty string. You might want to handle such cases explicitly.

7. **Output Buffers:**
Uncomment `ob_flush()` and `flush()` inside the loop to ensure the output is streamed as expected:

ob_flush();
   flush();

8. **Headers for CSV Download:**
Make sure the headers are set before any output is sent. For debugging, avoid `var_dump()` before the headers, or the file will not download properly.

### Debugging Steps:
1. Add logging for `$querystr` and `$pageposts`:

error_log($querystr);
   error_log(print_r($pageposts, true));

2. Temporarily disable CSV headers and print the output:

echo "<pre>";
   print_r($pageposts);
   echo "</pre>";
   exit;

3. Test the SQL query directly in the database (e.g., using phpMyAdmin or a database client) to see if it returns the expected results.

### Corrected Code Example:
Here’s an updated version of your code:

<?php
/* Template Name: Download Data */

set_time_limit(0);
ini_set('output_buffering', 'off');
ini_set('zlib.output_compression', 'Off');
global $wpdb;

$catex = intval($_GET['catex'] ?? -1);

$sqlcon = $catex !== -1 
    ? $wpdb->prepare("AND tt.taxonomy = 'category' AND t.term_id = %d", $catex)
    : "AND tt.taxonomy = 'category' AND t.term_id != '65'";

$sqlj = "
    JOIN $wpdb->term_relationships tr ON (p.ID = tr.object_id)
    JOIN $wpdb->term_taxonomy tt ON (tr.term_taxonomy_id = tt.term_taxonomy_id)
    JOIN $wpdb->terms t ON (tt.term_id = t.term_id)";

$querystr = "SELECT DISTINCT p.ID, p.post_title AS title, p.post_modified 
    FROM $wpdb->posts p  
    $sqlj 
    WHERE p.post_type = 'post' AND p.post_status = 'publish' 
    $sqlcon 
    ORDER BY p.post_date DESC";

$pageposts = $wpdb->get_results($querystr, OBJECT);

if (empty($pageposts)) {
    die('No posts found for the given criteria.');
}

header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename="post_report_data.csv"');
header('Pragma: no-cache');
header('Expires: 0');

$output = fopen('php://output', 'w');
fputcsv($output, ['Title', 'Url', 'Feature Image Url', 'Category', 'Revision Date', 'Meta Description']);

foreach ($pageposts as $post) {
    $url = wp_get_attachment_url(get_post_thumbnail_id($post->ID), 'thumbnail');
    $categories = implode(', ', array_map(function ($cat) {
        return $cat->cat_name;
    }, get_the_category($post->ID) ?: []));

    fputcsv($output, [
        $post->title,
        get_permalink($post->ID),
        $url,
        $categories,
        get_the_modified_date('Y-m-d H:i:s', $post->ID),
        get_post_meta($post->ID, '_yoast_wpseo_metadesc', true) ?: 'N/A'
    ]);

    ob_flush();
    flush();
}

fclose($output);
exit;

### Additional Notes:
– Test this code in a staging environment before deploying to production.
– Enable WP_DEBUG and WP_DEBUG_LOG in your WordPress `wp-config.php` file to capture errors:

define('WP_DEBUG', true);
  define('WP_DEBUG_LOG', true);

– Check the error log (`wp-content/debug.log`) for any issues.

Leave a Comment

Your email address will not be published. Required fields are marked *