it-swarm.com.de

Wie kann ich einen Dateidownload im WordPress-Backend erzwingen?

Ich möchte einem meiner WordPress-Plugins die Schaltfläche "Klicken zum Herunterladen" hinzufügen und bin mir nicht sicher, welchen Hook ich verwenden soll. Bisher scheint es zu funktionieren, 'admin_init' an diesen Code anzuhängen:

 header("Content-type: application/x-msdownload");
 header("Content-Disposition: attachment; filename=data.csv");
 header("Pragma: no-cache");
 header("Expires: 0");
 echo 'data';
 exit();

Dies scheint zu funktionieren, aber ich möchte nur sehen, ob es eine bewährte Methode gibt.

Danke, Dave

29
Dave Morris

Wenn ich Sie richtig verstehe, möchten Sie eine URL wie die folgende haben, deren Antwort auf den Browser der Inhalt ist, den Sie generieren, d. H. Ihre .CSV-Datei und keinen generierten Inhalt von WordPress?

http://example.com/download/data.csv

Ich denke, Sie suchen nach dem 'template_redirect'-Haken. Sie finden 'template_redirect' in /wp-includes/template-loader.php, einer Datei, mit der sich alle WordPress-Entwickler vertraut machen sollten. Es ist kurz und bündig und leitet alle Seiten, die nicht von Administratoren geladen werden, weiter.

Fügen Sie einfach Folgendes zur functions.php-Datei Ihres Themas oder zu einer anderen Datei hinzu, die Sie include in functions.php haben:

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();
  }
}

Notieren Sie den Test für die '/downloads/data.csv'-URL, indem Sie $_SERVER['REQUEST_URI'] überprüfen. Beachten Sie auch den hinzugefügten ,true,200 zu Ihrem header()-Aufruf, in dem Sie den Content-type festlegen. Dies liegt daran, dass WordPress den Statuscode 404"Not Found" festgelegt hat, da die URL nicht erkannt wird. Es ist jedoch kein Problem, da der trueheader() anweist, den von WordPress festgelegten 404 zu ersetzen und stattdessen den HTTP-Statuscode 200"Okay" zu verwenden.

Und so sieht es in FireFox aus ( Hinweis der Screenshot hat kein virtuelles Verzeichnis /downloads/, da es nach dem Aufnehmen und Kommentieren des Screenshots nur eine gute Idee war, ein virtuelles Verzeichnis '/downloads/' hinzuzufügen):

 Screenshot of a download URL for a CSV file 
(Quelle: mikeschinkel.com )

AKTUALISIEREN

Wenn Sie möchten, dass der Download über eine URL mit dem Präfix /wp-admin/ abgewickelt wird, um dem Benutzer den visuellen Hinweis zu geben, dass er durch eine Anmeldung geschützt ist, können Sie dies auch tun. Es folgt die Beschreibung eines Weges.

Ich habe diesmal eine Klasse mit dem Namen DownloadCSV eingekapselt und einen Benutzer "capacity" mit dem Namen 'download_csv' für die Rolle 'administrator'erstellt (lesen Sie über Rollen und Funktionen hier ) Sie könnten einfach die vordefinierte 'export'-Rolle huckepack nehmen, wenn Sie möchten, und wenn ja, einfach 'download_csv' durch 'export' suchen und ersetzen und den register_activation_hook()-Aufruf und die activate()-Funktion entfernen. Die Notwendigkeit eines Aktivierungs-Hooks ist übrigens einer der Gründe, warum ich diesen in ein Plugin verschoben habe, anstatt ihn in der functions.php-Datei des Themas zu speichern. *

Ich habe auch eine Menüoption "CSV herunterladen" aus dem Menü "Extras" mit add_submenu_page() hinzugefügt und sie mit der Funktion 'download_csv' verknüpft.

Zuletzt habe ich den Haken 'plugins_loaded' gewählt, weil es der früheste passende Haken war, den ich verwenden konnte. Sie könnten 'admin_init' verwenden, aber dieser Hook wird viel später ausgeführt (1130. Hook-Aufruf im Vergleich zum 3. Hook-Aufruf). Warum sollte WordPress dann mehr wegwerfen als nötig? (Ich habe mein Instrument Hooks-Plugin verwendet, um herauszufinden, welcher Hook verwendet werden soll.)

Im Hook überprüfe ich, ob meine URL mit /wp-admin/tools.php beginnt, indem ich die Variable $pagenow überprüfe. Überprüfe, ob current_user_can('download_csv') erfolgreich ist, und teste $_GET['download'], um festzustellen, ob sie data.csv enthält. Wenn ja, führen wir praktisch den gleichen Code wie zuvor aus. Ich entferne auch den ,true,200 aus dem Aufruf von header() im vorherigen Beispiel, da WordPress hier weiß, dass es sich um eine gute URL handelt, sodass der 404-Status noch nicht festgelegt wurde. Also hier ist dein 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();
}

Und hier ist ein Screenshot des aktivierten Plugins:  Screenshot of Plugin Page showing an activated plugin 
(Quelle: mikeschinkel.com )

Und zum Schluss hier noch ein Screenshot zum Auslösen des Downloads:  Screenshot of Downloading a file by URL from an option of the WordPress admin's Tools menu 
(Quelle: mikeschinkel.com )

38
MikeSchinkel

ein weiteres nützliches Plugin für den Export in CSV. kann für jemanden nützlich sein

    <?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();
3
Developer

admin_init Hook oder load- (page) Hook scheint zu funktionieren, WordPress wurde in diesem Zustand nicht als Header gesetzt. Ich verwende load- (page) Hook, weil es ausgeführt wird, wenn eine Verwaltungsmenüseite geladen wird. Sie können Ihr Skript für eine bestimmte Seite laden.

Sie können überprüfen, Load- (Seite) Hook auf WordPress Codex

Wenn Sie admin_init Hook verwenden, stellen Sie sicher, dass Sie nonce mithilfe von check_admin_referer verifizieren, oder ein anderes Skript, das die Bedingung erfüllt, gibt Ihre Downloaddatei aus.

2
Joko Wandiro