問題描述
我想添加一個 「點擊下載」 按鈕到我的一個 WordPress 插件,我不知道使用哪個鈎子。到目前為止,將’admin_init’ 掛接到此代碼似乎工作:
header("Content-type: application/x-msdownload");
header("Content-Disposition: attachment; filename=data.csv");
header("Pragma: no-cache");
header("Expires: 0");
echo 'data';
exit();
這似乎是有效的,但我只想看看是否有最佳實踐。
謝謝,戴夫
最佳解決方案
如果我正確理解您的意圖,您希望擁有一個如下所示的 URL,那麼對瀏覽器的響應將是您生成的內容,即您的.CSV 文件,並且沒有從 WordPress 生成的內容?
http://example.com/download/data.csv
我想你正在尋找'template_redirect'鈎。您可以在/wp-includes/template-loader.php 中找到'template_redirect',這是所有 WordPress 開發人員應該熟悉的文件; 它是短暫和甜蜜,路線每一個 non-admin 頁面加載,所以一定要看看它。
只需將以下內容添加到主題的 functions.php 文件或 include 在 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();
}
}
通過檢查 $_SERVER['REQUEST_URI']來注意'/downloads/data.csv' URL 的測試。另請注意添加,true,200 到您的 header()調用,您設置 Content-type; 這是因為 WordPress 會設置 404 “Not Found” 狀態代碼,因為它不能識別該 URL 。這是沒有問題的,因為 true 告訴 header()替換 404 WordPress 已經設置並使用 HTTP 200 “Okay” 狀態代碼。
FireFox 這是什麼樣子 (請注意,屏幕截圖沒有/downloads/虛擬目錄,因為在拍攝和註釋屏幕截圖後,似乎最好添加一個'/downloads/'虛擬目錄):
UPDATE
如果您希望從一個前綴為/wp-admin/的 URL 處理下載,以向用户提供受到登錄保護的可視指示,那麼您也可以這樣做:下面描述一種方法。
這次我封裝成一個類,稱為 DownloadCSV,併為 「管理員」 角色創建了一個名為 「download_csv」 的用户 「功能」(請閲讀此處的角色和功能) 您可以搭載預定義的 「導出」 角色,如果你喜歡,如果是這樣搜索& 用’export’ 替換’download_csv’,並刪除 register_activation_hook() 調用和 activate() 函數。順便説一句,需要一個激活鈎子是我把這個移植到插件而不是保留在主題的 functions.php 文件中的一個原因。*
我還使用 add_submenu_page()從”Tools” 菜單中添加了”Download CSV” 菜單選項,並將其鏈接到'download_csv'功能。
最後我選擇了'plugins_loaded'鈎子,因為它是我可以使用的最早的適當鈎子。你可以使用'admin_init',但這個鈎子運行得比較晚 (第 1130 次鈎子調用和第 3 個鈎子調用),所以為什麼讓 WordPress 做更多的 throw-away 工作呢? (我用我的 Instrument Hooks plugin 找出要使用的鈎子。)
在鈎子中,我檢查以確保我的 URL 從/wp-admin/tools.php 通過檢查 $ pagenow 變量開始,我驗證 current_user_can(‘download_csv’),如果通過,我測試 $ _GET [‘download’] 看它是否包含數據。 CSV; 如果是,我們幾乎運行與之前相同的代碼。我也刪除了前面的例子中的來自 header() 的 200 的 true,因為這裏 WordPress 知道這是一個很好的 URL,所以沒有設置 404 狀態。所以這裏是你的代碼:
<?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();
}
這裏是激活的插件的屏幕截圖:
最後這是一個觸發下載的屏幕截圖:
次佳解決方案
一個更有用的插件,用於導出到 CSV 。可能對某些人有用
<?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();
參考文獻
注:本文內容整合自 Google/Baidu/Bing 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。


