I would like to export all selected items from the items-view of my component.

To do so I modified my view and inserted a new button to the

JToolBarHelper::custom('items.exportcsv', 'download', '', 'COM_BESTIA_EXPORT', true);

I also modified the controller:

/**
 * exportcsv function.
 * 
 * @access public
 * @return void
 */
public function exportcsv()
{

    $jinput                 =           JFactory::getApplication()->input;
    $ids                    =           $jinput->get('cid', '', 'array');
    $modelitems     =           $this->getModel();

    $array                  =           array();

    foreach($ids as $id)
    {
        $item                           =   $modelitems->getItem($id);      
        $array[$item->id]['itemid'] =   $item->itemid;
    }

    $csv                                    =       ArrayHelper::exportArrayToCSV($array, "items-report");
    $this->setRedirect('index.php?option=bestia&view=items', false);        

}       

Now I created a function in a helper to create the download:

/**
 * exportArrayToCSV function.
 * 
 * @access public
 * @static
 * @param mixed $array
 * @return void
 */
public static function exportArrayToCSV($array, $filename, $delimiter=";")
{
    $config                         =   JFactory::getConfig();
    $tmppath                        =   $config->get('tmp_path');

    $keys                           =   array_keys($array);

    if(is_dir($tmppath))
    {
        $filename                   =   "$filename.csv";
        $filepath                   =   "$tmppath/$filename";
        $file                       =   new SplFileObject($filepath, 'w');

        $file->fputcsv(array_keys($array[$keys[0]]),$delimiter);

        foreach ($array as $fields) 
        {
            $file->fputcsv($fields,$delimiter);
        }

        if(file_exists($filepath))
        {   
            header ( 'Content-Description: File Transfer' );
            header ( 'Content-Type: application/force-download' );
            header ( 'Content-Type: application/octet-stream' );
            header ( 'Content-Disposition: attachment; filename=' . $filename ); 
            header ( 'Expires: 0' );
            header ( 'Cache-Control: must-revalidate' );
            header ( 'Pragma: public' );
            header ( 'Content-Length: ' . filesize ($filepath) );
            ob_clean(); 
            flush();
                readfile ($filepath);
                unlink($filepath); 
            exit();
        }
        else                            return false;   
    }
    else                                return false;       
}

This also works fine.

But I mentioned a strange behavior: If I download a CSV and change the filter after downloading in the searchbar like this:

enter image description here

The file is downloaded again.

I think the problem is somewhere around here:

            ob_clean(); 
            flush();
                readfile ($filepath);
                unlink($filepath); 
            exit();

But I do not know how to solve it.

  • 1
    It seems somehow you are requesting for same task (items.exportcsv) again on change of your filter or submitting the same form you will need to check code where you handle the these filter onchange event. – Lokendra Joshi Feb 19 '16 at 5:44
  • Hello... Yes, the exit(); in the download-code prevents joomla from reloading the site and clearing the task-value in the hidden field. Unfortunately I did not find out how to create a download with PHP without using die; or exit; – MyFault Feb 19 '16 at 19:41
  • Provide me more information are you submitting a from on change of your filter (for example onchange="this.form.submit();" ) if so then you will need to change task before submitting the form. – Lokendra Joshi Feb 20 '16 at 5:48
  • Hello, yes, I'm using this.form.submit - the question is: How can I change the task? – MyFault Feb 20 '16 at 10:12
  • this.form.task = ''; You can simply go like this. Like this.form.inputName – Alexandr Jan 18 '17 at 19:52

This is because each search form change triggers form submit

So you need to return "task" field to it's default value, wich is empty by default

function submitForm(){ this.form.submit(); jQuery('input[name="task"]').val("");  }

Check if you have hidden field named task if not then add following:

<input type="hidden" value="" name="task">

Then change its value by editing on change event as follows:

onchange="submitForm();"

Then add following small script:

<script>
  function submitForm(){
    this.form.task = 'subcontroller.csvDownloadTask';
    this.form.submit();
    this.form.task = '';
  }
</script>

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.