Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Joomla - Force File Download / CSV Export

Tags:

php

csv

joomla

I'm in need of help... this is my first time asking a question in SO, so please be kind :)

I'm trying to force-download a file from php, so when the user hits a certain button, he gets a file download. The file is a csv (email, username) of all registered users.

I decided to add this button to the admin > users screen, as you can see in this screenshotenter image description here.

So I added the following code to the addToolbar function in administrator/components/com_users/views/users/view.html.php:

JToolBarHelper::custom('users.export', 'export.png', 'export_f2.png', 'Exportar', false);

This button is mapped to the following function in the com_users\controller\users.php controller:

public function exportAllUsers() {
    ob_end_clean();
    $app = JFactory::getApplication();

    header("Content-type: text/csv");
    header("Content-Disposition: attachment; filename=ideary_users.csv");
    header("Pragma: no-cache");
    header("Expires: 0");

    echo "email,name\n";

    $model = $this->getModel("Users");
    $users = $model->getAllUsers();

    foreach ($users as $user) {
        echo $user->email . ", " . ucwords(trim($user->name)) . "\r\n";
    }

    $app->close();

}

Now, this is actually working perfectly fine.

The issue here is that after I download a file, if I hit any button in the admin that causes a POST, instead of it performing the action it should, it just downloads the file over again! For example:

  • I hit the "Export" button
  • "users.csv" downloads
  • Then, I hit the "search" button
  • "users.csv" downloads... what the hell?

I'm guessing that when I hit the export button, a JS gets called and sets a form's action attribute to an URL... and expects a response or something, and then other button's are prevented from re-setting the form's action attribute. I can't think of any real solution for this, but I'd rather avoid hacks if possible.

So, what would be the standard, elegant solution that joomla offers in this case?

like image 818
Taro Avatar asked Dec 19 '25 19:12

Taro


2 Answers

I think the bit you're missing is the Javascript that handles toolbar buttons, if you're just doing default actions New/Delete/Publish/Unpublish etc you don't need to add anything.

However, for custom buttons you usually have to override the default behaviour (which sets some hidden form values as they expect a page to be returned, causing a refresh and never hitting the problem you've encountered).

So normally a button relies on the submitbutton() from includes/js/joomla.javascript.js

function submitbutton(pressbutton) {
  submitform(pressbutton);
}

Which amongst other things sets the value of the task input field of the #adminForm to the buttons task, i.e. in your case user.export

You will need to add some Javascript to com_users/views/users/tmpl/default.php to call your method via window.location or similar.

As you don't want the default behaviour you need to create your own override for submitbutton() something like this:

function submitbutton(pressbutton) {
    // Check if it's your button
    if(pressbutton == 'users.export') {
        // Call your method with something like this:
        window.location = 'index.php?option=com_users&task=users.export'
        // That should be it, this way you don't set the task value for future clicks
    } else {
      // If not follow the normal path
      document.adminForm.task.value=pressbutton;
      submitform(pressbutton);
    }
}

You can find more here in the archived section of the Joomla Doc's website.

like image 84
Craig Avatar answered Dec 22 '25 10:12

Craig


Add this code to your view controller

function export(){

    ob_end_clean();
    $app = JFactory::getApplication();

    header("Content-type: text/csv");
    header("Content-Disposition: attachment; filename=slic_student.csv");
    header("Pragma: no-cache");
    header("Expires: 0");

    echo "ID,School Name,Student Name,Student No\n";

    $model = $this->getModel("students");
    $users = $model->export_query();

    foreach ($users as $user) {
        echo $user->student_id . ", " . ucwords(trim($user->school_name)) . ", " . ucwords(trim($user->student_name)) . ", " . ucwords(trim($user->student_no)) . "\r\n";
    }
    $app->close();
}

Add this to the view.html.php

  JToolBarHelper::custom('students.export','','', 'CSV Export', false);
like image 35
Mohamed Aroos Avatar answered Dec 22 '25 08:12

Mohamed Aroos



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!