WordPress 백엔드에서 파일을 강제로 다운로드하려면 어떻게해야합니까?


30

WordPress 플러그인 중 하나에 "Click to download"버튼을 추가하고 싶습니다. 어떤 후크를 사용할지 잘 모르겠습니다. 지금까지이 코드에 '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();

이것은 효과가있는 것 같지만 모범 사례가 있는지 확인하고 싶습니다.

고마워, 데이브

답변:


39

올바르게 이해하면 브라우저에 대한 응답이 생성하는 컨텐츠, 즉 파일이며 WordPress에서 생성 된 컨텐츠가 아닌 다음과 같은 URL 을 원 .CSV하십니까?

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

나는 당신이 'template_redirect'갈고리를 찾고 있다고 생각합니다 . 모든 WordPress 개발자가 익숙해 져야 할 파일이 어느 파일 'template_redirect'/wp-includes/template-loader.php있는지 찾을 수 있습니다 . 짧고 달콤하며 관리자가 아닌 모든 페이지로드를 라우팅하므로 확인하십시오.

그냥 테마의에 다음을 추가 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();
  }
}

'/downloads/data.csv'를 검사 하여 URL 테스트를 확인하십시오 $_SERVER['REQUEST_URI']. 또한 추가주의 ,true,200당신에게 header()당신이 설정 호출 Content-type; 이는 WordPress가 URL을 인식하지 못하기 때문에 404 "찾을 수 없음" 상태 코드를 설정했기 때문입니다. WordPress 를 대체 하고 HTTP "Okay" 상태 코드를 대신 사용하라는 true지시 header()에 따라 문제는 없습니다 .404200

그리고 여기가 파이어 폭스에서의 모습입니다 ( 참고 이없는 화면을 /downloads/스크린 샷을 복용하고 주석 후 그냥 추가하는 것이 생각처럼 보였다 때문에 가상 디렉터리를 '/downloads/'가상 디렉토리) :

CSV 파일의 다운로드 URL 스크린 샷
(출처 : mikeschinkel.com )

최신 정보

접두사가 붙은 URL에서 다운로드를 처리 /wp-admin/하여 사용자에게 로그인으로 보호되고 있음을 시각적으로 표시하려면 다운로드를 수행해야합니다. 한 가지 방법에 대한 설명은 다음과 같습니다.

나는 클래스로이 시간을 캡슐화라고 DownloadCSV하고, 사용자 생성에 "기능" 이라고 'download_csv'에 대한 'administrator'역할을 (역할 및 기능에 대해 읽어 여기에 ) 그냥 미리 정의의 오프 피기 백 수 'export'당신이 경우 그래서 그냥 검색 및 대체하면 같은 역할 'download_csv'로 호출과 기능을 'export'제거하십시오 . 그런데 활성화 훅이 필요하기 때문에 테마 파일 에 보관하지 않고 플러그인으로 옮겼습니다 . * register_activation_hook()activate()functions.php

또한 "도구" 메뉴 에서 " CSV 다운로드" 메뉴 옵션 을 추가하여 기능에 연결했습니다 .add_submenu_page()'download_csv'

마지막으로 'plugins_loaded'후크는 내가 사용할 수있는 가장 적절한 후크이기 때문에 후크를 선택했습니다 . 사용할 수는 'admin_init'있지만 그 후크는 훨씬 나중에 실행됩니다 (1130 번째 후크 호출 대 3 번째 후크 호출) 왜 WordPress가 필요한 것보다 더 많은 일을 처리해야합니까? (내 장비 후크 플러그인 을 사용하여 사용할 후크를 파악했습니다.)

후크 /wp-admin/tools.php에서 $pagenow변수 를 검사하여 URL로 시작 하는지 확인하고 current_user_can('download_csv'), 확인 하면 해당 URL이 $_GET['download']포함되어 있는지 테스트 합니다 data.csv. 그렇다면 실제로 이전과 동일한 코드를 실행합니다. 또한 이전 예제에서 ,true,200호출을 제거합니다. header()여기서 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();
}

다음은 활성화 된 플러그인의 스크린 샷입니다. (source : mikeschinkel.com )활성화 된 플러그인을 보여주는 플러그인 페이지의 스크린 샷

그리고 마지막으로 다운로드를 시작한 스크린 샷입니다 : (source : mikeschinkel.com )WordPress 관리자 도구 메뉴 옵션에서 URL로 파일 다운로드 스크린 샷


마이크, 도와 줘서 고마워 이 기능의 유일한 장점은 백엔드에서 파일을 다운로드하고 싶다는 것입니다. template_redirect가 백엔드에서 작동하지 않는 것 같습니다. admin_init를 사용하지 않으면 대신 사용해야하는 것이 궁금합니다. admin_init는 지금 나를 위해 작동하는 것 같습니다. 적어도 단기적으로는 고수 할 수 있습니다. 소수의 사람들 만 사용할 수있는 사소한 기능입니다.
Dave Morris

@Dave Morris- "백엔드"의 의미를 정의 할 수 있습니까 ? 서버를 의미합니까? 그렇다면 'template_redirect'가장 확실하게 서버에서 실행됩니다. 그렇지 않다면 완전히 혼란 스러웠습니다. 우려를 분명히 할 수 있습니까? 미리 감사드립니다.
MikeSchinkel

@Dave : "백엔드"라는 관리 영역을 의미하는 경우에도 여전히 작동합니다. 다운로드 URL은 /downloads/data.csv존재하지 않는 파일 인으로 시작하므로 WordPress "프론트 엔드"가이 요청을 처리하여에 도달 template-redirect합니다. 관리 영역에서이 프론트 사이드 URL을 가리키는 링크를 작성하기 만하면됩니다. (이 방법으로, 당신은 무료로 관리자 로그인 보호를 얻지 못한다고 말해야합니다-URL을 아는 사람은 파일을 다운로드 할 수는 있지만 쉽게 고칠 수있는 방법이 있습니까?)
Jan Fabry

@ Jan Fabry-아, 이제 이해합니다. 에 의해 "백 엔드" 그는 오른쪽 관리자 내에서 의미? 그는 current_user_can()위의 코드와 함께 함수 를 사용 하거나 다른 접근법을 취할 수 있습니다. 이 의견 후에는 답변에 업데이트를 추가하겠습니다.
MikeSchinkel

예, 죄송합니다.이 사이트에서 이메일 알림을받지 못했습니다. 답장 지연이 설명되어 있습니다. "백엔드"라고 말했을 때 실제로 WordPress의 관리 영역을 언급하고있었습니다. 미안합니다. template_redirect를 사용 해보고 어떤 일이 발생하는지 보겠습니다. 감사! ~ Dave
Dave Morris

3

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

2

admin_init Hook 또는 load- (page) Hook가 작동하는 것 같습니다. WordPress가이 상태에서 헤더로 설정되지 않았습니다. 관리 메뉴 페이지가로드 될 때로 드되기 때문에 로드 (페이지) 후크를 사용하고 있습니다. 특정 페이지에 대한 스크립트를로드 할 수 있습니다.

워드 프레스 코덱스에서로드 (페이지) 후크를 확인할 수 있습니다

당신이 사용하는 경우 admin_init의 후크 메이크업을 확인하기 위해 비표 확인 하여 check_admin_referer 출력 귀하의 다운로드 파일을 얻을 것이다 어쩌면 상태를 전달하거나 다른 스크립트를.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.