My CSV File isn't giving me filtered results

Hi

I have written php code that displays a list of all tenders in a database table.
The user can sort on options displayed in the dropdown box and once a filter option is selected, and the Go button clicked, the view updates based on the selection. A filter example would be “Open”, “Closed”, “Awarded” etc.

This part is working for me.

However, I was trying to write some php code so that when you click the Download button image on the page, a csv file is created containing the contents of the filtered view that is currently displayed to the user.

This part isn’t working for me and any help pointing me in the right direction would be much appreciated.

This is my tenders function file:

<?php

function MakeOpts($options, $default)
{
    $html = ""; 

    foreach ($options as $name => $value) 
    {
       if ($value === $default)
      { 
	$sel = " selected";
      } 
      else
      { 
	$sel = "";
      }

    $html .= "\t<option value='$value'$sel>$name</option>\n";
  }

  return $html;
}

function CreateDownloadFile($sTemp, $sFile, $rows)
{
      $sHeaders	= "";  
      $sContents          = "";
      $sNewLine	= "\n";

      $sFileTo = "../wp-content/plugins/my-tenders/" . $sFile;
      @rename($sFile, $sFileTo);

      $fp = fopen($sFileTo, "w") or die("Unable to open file!");
      $sHeaders = "ID," . "Name," . "Type," . "Issued," . "Closed," . "Status," . "Awarded To," . "Description," . $sNewLine;

     if (rows)
     {
 	$sContents = $sHeaders . $sTemp;
     }
    else
    {
                 $sContents = $sHeaders . "No Matching Records Found!";
    }
      
     fwrite($fp, $sContents);
     fclose($fp);
}

Here is my tenders.list file:

<?php


function my_tenders_list() 
{
    ?>
    <link type="text/css" href="<?php echo WP_PLUGIN_URL; ?>/my-tenders/css/style-admin.css" rel="stylesheet" />
    <script language="JavaScript" src="<?php echo WP_PLUGIN_URL; ?>/my-tenders/js/validate-tenders.js"></script> 
     
     <?php 
    $options = array ('All' => '',  'Open' => 'Open',  'Closed' => 'Closed',  'Awarded' => 'Awarded',
  	                'Archived' => 'Archived',  'Cancelled' => 'Cancelled');

    if (isset($_POST["filter"])) 
    { 
	$filter = $_POST["filter"] ;
    } 
    else
    { 
	$filter = "All";
    } 

    $sFilter = $filter;
    $tmp = WP_PLUGIN_URL . "/my-tenders/img/town-logo.png";
    $tmp1 = WP_PLUGIN_URL . "/my-tenders/img/btnDownload.jpg";

    ?>

    <div class="wrap">
       <img src="<?php echo $tmp ?>" />
        <h2 style="font-size:28px;color:#0c6bb5;">Tenders List</h2>
        <div class="tablenav top">
            <div class="alignleft actions">
                <a href="<?php echo admin_url('admin.php?page=my_tenders_create'); ?>">Add New Tender</a>

                 <br/>
                 <form name="Form1" action="" method="POST">
	<input type="hidden" id="ftype" name="ftype" value="<?php echo $sFilter; ?>" >
	<select name="filter" onchange="FilterTenders(this)">
	<?= MakeOpts($options, $filter) ?>
	</select>
	&nbsp;
                 <input type="submit" class="fbutton-small" value="GO">
                 </form>
	<br/><br/>
            </div>
            <br class="clear">
        </div>

        <?php
        global $wpdb;
        global $sTemp;
        global $sFile;

        $sFile		= "tenders-list.csv";
        $sDelimiter		= ",";
        $sNewLine		= "\n";

        $sFilter		=  $_POST["ftype"];
        $table_name  		= $wpdb->prefix . "tenders";

        if ( ($sFilter == "All") || ($sFilter == "") )
        {
	  $rows 	= $wpdb->get_results("SELECT * from $table_name ORDER BY id");
        }
       else
       {
	  $rows 	= $wpdb->get_results("SELECT * from $table_name  WHERE status = '$sFilter' ORDER BY id");
       }
       ?>

      <?php

       if (! $rows)
       {
	  echo "<div style='text-align:left;margin-top:160px;'>";
	  echo "No tender record(s) matching $sFilter were found. Try again.</div>";
                   return;
       }
       ?>

        <table class="wp-list-table widefat fixed striped posts" id="round" width=100%>
            <tr>
                <th class="table-hdr">ID</th>
                <th class="table-hdr">Name</th>
                <th class="table-hdr">Type</th>
                <th class="table-hdr">Issued</th>
                <th class="table-hdr">Closed</th>
                <th class="table-hdr">Status</th>
                <th class="table-hdr">Awarded</th>
                <th class="table-hdr">Description</th>
                <th class="table-hdr">&nbsp;</th>
            </tr>

            <?php foreach ($rows as $row) 
            { 
	$sTemp = $sTemp . $row->id 		. $sDelimiter;
	$sTemp = $sTemp . $row->name 	. $sDelimiter;
	$sTemp = $sTemp . $row->type 	. $sDelimiter;
	$sTemp = $sTemp . $row->issued	. $sDelimiter;
	$sTemp = $sTemp . $row->closed	. $sDelimiter;
	$sTemp = $sTemp . $row->status	. $sDelimiter;
	$sTemp = $sTemp . $row->awarded	. $sDelimiter;
	$sTemp = $sTemp . $row->desc	. $sDelimiter;
	$sTemp = $sTemp . $sNewLine;
            ?>

            <tr>
                    <td><?php echo $row->id; ?></td>
                    <td><?php echo $row->name; ?></td>
                    <td><?php echo $row->type; ?></td>
                    <td><?php echo $row->issued; ?></td>
                    <td><?php echo $row->closed; ?></td>
                    <td><?php echo $row->status; ?></td>
                    <td><?php echo $row->awarded; ?></td>
                    <td><?php echo substr($row->desc, 0, 60); ?></td>
                    <td><a href="<?php echo admin_url('admin.php?page=my_tenders_update&id=' . $row->id); ?>">Update</a></td>
             </tr>
            <?php } ?>
        </table>

         <br/><br/>
         <?php
                echo "<a href='$sFile' download>";
                echo "<img src='$tmp1' border='0' alt='Download' onclick='CreateDownloadFile($sTemp, $sFileTo, $rows)' /></a>";
         ?>
    </div>
    <?php
}

?>






Is this typo in the live code?

  if (rows)

If that doesn’t help, can you describe the way that it is not working? Too many records in the CSV file, too few, none, error messages?

Hi

That was a typo in the code I posted.

I am getting a well-formed csv file, but it is giving me all the records and not a filtered
record.

My issue is with this area:

When the download button is clicked, I need to create the download file first and then have the download fire. I’m not doing this the right way.

echo "<a href='$sFile' download>";
 echo "<img src='$tmp1' border='0' alt='Download' onclick='CreateDownloadFile($sTemp, $sFileTo, $rows)' /></a>";

Ah, I see. I’ve seen code that does what you need on here, but can’t quite remember how far back. The link would basically call your PHP that would run the query, create the CSV and then instruct the browser to give the “save as” dialog.

Another option might be to create the CSV file at the same time as you’re displaying the results, so that by the time the browser has displayed the “download” button, it’s all there in the file ready for download. One of the down sides of that approach (and there may be many) is that you need to consider the filename - if someone else runs the same page with different options, by the time the user clicks the download button the information in the file may have changed.

HI

I’ve done that in the code I attached.
I think I should re-write my issue.
Thanks anyways.

I must admit I’m a bit confused by this line

echo "<img src='$tmp1' border='0' alt='Download' onclick='CreateDownloadFile($sTemp, $sFileTo, $rows)' /></a>";

which seems to be rendering the html code for a hyperlink which calls your CreateDownloadFile() function, but that appears to be a PHP function, so I can’t see how it would work. I can see (now) how you build up the $sTemp variable with your contents, but I can’t see where you write the information into the file. Yet you said it works and you have a file out of it. So I’m confused because what, in my relatively limited knowledge should not work, seems to work.

Hi

I think I forgot to attach my functions.php file.
I think this is what is happening…

I am creating the csv file each time that I render the results. So on my server in a folder the csv file is being created successfully.

It appears that when I click the download link, I don’t get the latest csv filtered file, I get the previous one.

So I doing something in the wrong order.

That seems like a waste of CPU cycles and disk space if you generate and store something that will not be accessed every time. It would be better to create a separate URL where the CSV will be generated on the fly and send to the browser directly (no temp file on disk, it’s not needed).

The easiest way to create CSV files btw is by using fputcsv, which is a lot easier that combining everything together by hand.

For example:

$fp = fopen('php://memory', 'w');

fputcsv($fp, ['Hello', 'world']);
fputcsv($fp, ['How', 'are']);
fputcsv($fp, ['you', 'doing today?']);

rewind($fp);
echo stream_get_contents($fp);

Hi

I will change how it writes later, just want to get the download working.
Still doing the same thing.
I’m going to have to step back and work on something else.

Thanks for trying to help.

I think you are mixing things up. CreateDownloadFile is a PHP function which gets executed on the server side before the browser receives the web page.

But the code below is JavaScript NOT PHP:

onclick='CreateDownloadFile($sTemp, $sFileTo, $rows)

This tries to call a JS function when onclick event is fired on the client side (browser). When the server sends the web page to your browser the PHP function does not exist anymore.

A simple CSV creation & download solution:

csv.php

<html>
<body>
<a href="create.php">Download CSV</a>
</body>
</html>

create.php

header('Content-Type: application/csv');
header('Content-Disposition: attachment; filename="test.csv";');

$fp = fopen('php://memory', 'w');

fputcsv($fp, ['Hello', 'world']);
fputcsv($fp, ['How', 'are']);
fputcsv($fp, ['you', 'doing today?']);

rewind($fp);
echo stream_get_contents($fp);

You could provide GET parameters to the create script for example to modify filename or to define how the CSV is structured in the create.php.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.