Reputation: 1542
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 screenshot.
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'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?
Upvotes: 3
Views: 3429
Reputation: 11
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);
Upvotes: 1
Reputation: 9330
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.
Upvotes: 2