J'aimerais ajouter un bouton "Cliquez pour télécharger" sur l'un de mes plugins WordPress, et je ne suis pas sûr du hook à utiliser. Jusqu’à présent, lier 'admin_init' à ce code semble fonctionner:
header("Content-type: application/x-msdownload");
header("Content-Disposition: attachment; filename=data.csv");
header("Pragma: no-cache");
header("Expires: 0");
echo 'data';
exit();
Cela semble fonctionner, mais je veux juste voir s'il existe une meilleure pratique.
Merci Dave
Si je vous ai bien compris, vous voulez avoir une URL du même type / dont le navigateur répondra au contenu que vous générez, c’est-à-dire votre fichier .CSV
et aucun contenu généré à partir de WordPress?
http://example.com/download/data.csv
Je pense que vous recherchez le hook 'template_redirect'
. Vous pouvez trouver 'template_redirect'
dans /wp-includes/template-loader.php
, un fichier avec lequel les développeurs WordPress devraient se familiariser; il est court et agréable et dirige chaque chargement de page non-administrateur, alors jetez-y un coup d'œil.
Ajoutez simplement ce qui suit au fichier functions.php
de votre thème ou dans un autre fichier dans lequel vous include
dans functions.php
:
add_action('template_redirect','yoursite_template_redirect');
function yoursite_template_redirect() {
if ($_SERVER['REQUEST_URI']=='/downloads/data.csv') {
header("Content-type: application/x-msdownload",true,200);
header("Content-Disposition: attachment; filename=data.csv");
header("Pragma: no-cache");
header("Expires: 0");
echo 'data';
exit();
}
}
Notez le test pour l'URL '/downloads/data.csv'
en inspectant $_SERVER['REQUEST_URI']
. Notez également le ,true,200
ajouté à votre appel header()
où vous définissez le Content-type
; En effet, WordPress aura défini le code d'état 404
"Introuvable"} _ _ car il ne reconnaît pas l'URL. Ce n'est pas un problème cependant puisque la true
indique à header()
de remplacer le 404
défini par WordPress et d'utiliser le code HTTP 200
"OK" à la place.
Et voici à quoi cela ressemble dans FireFox ( Remarque la capture d'écran ne possède pas de répertoire virtuel /downloads/
car après avoir pris et annoté la capture d'écran, il semblait simplement judicieux d'ajouter un répertoire virtuel '/downloads/'
). :
(source: mikeschinkel.com )
Si vous souhaitez que le téléchargement soit géré à partir d'une URL avec le préfixe /wp-admin/
pour donner à l'utilisateur une indication visuelle qu'il est protégé par un identifiant, vous pouvez également le faire; la description d'une manière suit.
J'ai encapsulé cette fois dans une classe appelée DownloadCSV
et créé un utilisateur "possibilité" appelé 'download_csv'
pour le rôle 'administrator'
(à propos des rôles et des capacités ici ) Vous pouvez simplement utiliser le rôle 'export'
prédéfini si vous le souhaitez. Dans ce cas, il suffit de rechercher & remplacer 'download_csv'
avec 'export'
et de supprimer l'appel register_activation_hook()
et la fonction activate()
. Soit dit en passant, la nécessité d'un raccordement d'activation est l'une des raisons pour lesquelles je l'ai déplacé dans un plugin au lieu de conserver le fichier functions.php
du thème. *
J'ai également ajouté une option de menu "Télécharger CSV" du menu "Outils" à l'aide de add_submenu_page()
et l'a liée à la fonctionnalité 'download_csv'
.
Enfin, j’ai choisi le crochet 'plugins_loaded'
car c’était le premier crochet approprié que je pouvais utiliser. Vous pouvez utiliser 'admin_init'
mais ce hook est exécuté beaucoup plus tard (1130ème appel de hook par rapport au troisième appel de hook), alors pourquoi laisser WordPress faire plus de travail que nécessaire? (J'ai utilisé mon plugin Instrument Hooks pour déterminer quel hook utiliser.)}
Dans le crochet, je vérifie que mon URL commence par /wp-admin/tools.php
en inspectant la variable $pagenow
, je vérifie que current_user_can('download_csv')
et si cela réussit, je teste $_GET['download']
pour voir si elle contient data.csv
; Si oui, nous utilisons pratiquement le même code que précédemment. J'ai également supprimé le ,true,200
de l'appel à header()
dans l'exemple précédent, car ici WordPress sait que c'est une bonne URL et n'a donc pas encore défini le statut 404. Alors voici votre code:
<?php
/*
Plugin Name: Download CSV
Author: Mike Schinkel
Author URI: http://mikeschinkel.com
*/
if (!class_exists('DownloadCSV')) {
class DownloadCSV {
static function on_load() {
add_action('plugins_loaded',array(__CLASS__,'plugins_loaded'));
add_action('admin_menu',array(__CLASS__,'admin_menu'));
register_activation_hook(__FILE__,array(__CLASS__,'activate'));
}
static function activate() {
$role = get_role('administrator');
$role->add_cap('download_csv');
}
static function admin_menu() {
add_submenu_page('tools.php', // Parent Menu
'Download CSV', // Page Title
'Download CSV', // Menu Option Label
'download_csv', // Capability
'tools.php?download=data.csv');// Option URL relative to /wp-admin/
}
static function plugins_loaded() {
global $pagenow;
if ($pagenow=='tools.php' &&
current_user_can('download_csv') &&
isset($_GET['download']) &&
$_GET['download']=='data.csv') {
header("Content-type: application/x-msdownload");
header("Content-Disposition: attachment; filename=data.csv");
header("Pragma: no-cache");
header("Expires: 0");
echo 'data';
exit();
}
}
}
DownloadCSV::on_load();
}
Et voici une capture d'écran du plugin activé:
(source: mikeschinkel.com )
Et enfin, voici une capture d'écran du déclenchement du téléchargement:
(source: mikeschinkel.com )
encore un plugin utile pour exporter en CSV. peut être utile à quelqu'un
<?php
class CSVExport
{
/**
* Constructor
*/
public function __construct()
{
if(isset($_GET['download_report']))
{
$csv = $this->generate_csv();
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private", false);
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"report.csv\";" );
header("Content-Transfer-Encoding: binary");
echo $csv;
exit;
}
// Add extra menu items for admins
add_action('admin_menu', array($this, 'admin_menu'));
// Create end-points
add_filter('query_vars', array($this, 'query_vars'));
add_action('parse_request', array($this, 'parse_request'));
}
/**
* Add extra menu items for admins
*/
public function admin_menu()
{
add_menu_page('Download Report', 'Download Report', 'manage_options', 'download_report', array($this, 'download_report'));
}
/**
* Allow for custom query variables
*/
public function query_vars($query_vars)
{
$query_vars[] = 'download_report';
return $query_vars;
}
/**
* Parse the request
*/
public function parse_request(&$wp)
{
if(array_key_exists('download_report', $wp->query_vars))
{
$this->download_report();
exit;
}
}
/**
* Download report
*/
public function download_report()
{
echo '<div class="wrap">';
echo '<div id="icon-tools" class="icon32">
</div>';
echo '<h2>Download Report</h2>';
//$url = site_url();
echo '<p>Export the Users';
}
/**
* Converting data to CSV
*/
public function generate_csv()
{
$csv_output = '';
$table = 'users';
$result = mysql_query("SHOW COLUMNS FROM ".$table."");
$i = 0;
if (mysql_num_rows($result) > 0) {
while ($row = mysql_fetch_assoc($result)) {
$csv_output = $csv_output . $row['Field'].",";
$i++;
}
}
$csv_output .= "\n";
$values = mysql_query("SELECT * FROM ".$table."");
while ($rowr = mysql_fetch_row($values)) {
for ($j=0;$j<$i;$j++) {
$csv_output .= $rowr[$j].",";
}
$csv_output .= "\n";
}
return $csv_output;
}
}
// Instantiate a singleton of this plugin
$csvExport = new CSVExport();
admin_init Hook ou load- (page) Hook semble fonctionner, WordPress n'a pas été défini d'en-tête dans cet état. J'utilise load- (page) Hook car il s'exécute lorsqu'une page de menu d'administration est chargée. Vous pouvez charger votre script pour une page spécifique.
Vous pouvez vérifier charger- (page) Hook sur WordPress Codex
Si vous utilisez admin_init Hook, assurez-vous de verify nonce utilisez check_admin_referer ou un autre script. La condition peut éventuellement renvoyer votre fichier téléchargé.