WordPress arka ucunda bir dosyayı nasıl zorlayabilirim?


30

WordPress eklentilerimden birine "İndirmek için tıkla" düğmesi eklemek istiyorum ve hangi kancayı kullanacağımdan emin değilim. Şimdiye kadar, 'admin_init' i bu koda kopyalamak işe yarayacak gibi görünüyor:

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

Bu iş gibi görünüyor, ama sadece orada en iyi uygulama olup olmadığını görmek istiyorum.

Sağol Dave.

Yanıtlar:


39

Sizi doğru anlarsam, bir URL’ye , tarayıcıya verdiğiniz içerik, yani .CSVdosyanız ve WordPress’ten oluşturulan içerik yok mu?

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

Bence sen aradığın 'template_redirect' kancayı . Sen bulabilirsiniz 'template_redirect'içinde /wp-includes/template-loader.phphangi tüm WordPress geliştiricileri aşina gereken bir dosyadır; kısa ve tatlıdır ve yönetici olmayan her sayfa yükünü yönlendirir, bu yüzden bir göz attığınızdan emin olun.

Aşağıdakileri temanın functions.phpdosyasına veya içinde bulunduğun başka bir dosyaya ekle 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 için yapılan testi inceleyerek not edin $_SERVER['REQUEST_URI']. Ayrıca eklenen not ,true,200sizin için header()belirlediğiniz bir görüşme Content-type; Bunun nedeni, WordPress’in URL’yi tanımıyor olması nedeniyle 404 “Bulunamadı” durum kodunu ayarlamış olmasıdır . WordPress'in yerini aldığını ve bunun yerine HTTP "Tamam" durum kodunu kullandığını truesöylediği header()için sorun değil.404200

Ve işte FireFox'ta böyle görünüyor ( Not bir yok ekran görüntüsü /downloads/ekran görüntüsü alarak ve annotating sonra sadece bir eklemek iyi bir fikir gibi görünüyordu çünkü sanal dizin '/downloads/'sanal dizini):

CSV dosyası için indirme URL'sinin ekran görüntüsü
(kaynak: mikeschinkel.com )

GÜNCELLEŞTİRME

Yüklemenin, önceden eklenmiş bir URL’den ele alınmasını istiyorsanız, /wp-admin/ , kullanıcıya bir giriş tarafından korunduğuna dair görsel bir gösterge vermek için önceden istiyorsanız, bunu da yapabilirsiniz; bir yolun açıklaması takip eder.

Ben bir sınıfa bu kez kapsüllü olarak adlandırılan DownloadCSVve bir kullanıcının oluşturduğu için "yeteneği" denilen 'download_csv'için 'administrator'rolü (konumları ve kabiliyetleri hakkında okuyun burada ) Sadece önceden tanımlanmış kapalı omzunda olabilir 'export'eğer ve bu yüzden sadece arama ve değiştirme durumunda gibi rolü 'download_csv'ile 'export've register_activation_hook()çağrıyı ve activate()işlevi kaldırın . Bu arada, bir etkinleştirme kancaya duyulan ihtiyaç, temanın functions.phpdosyasında saklamak yerine bunu bir eklentiye taşımamın bir nedeni . *

Ayrıca kullanarak "Araçlar" menüsünden " CSV İndir" menü seçeneğini ekledim.add_submenu_page() ve 'download_csv'kabiliyetle ilişkilendirdim.

Son olarak 'plugins_loaded'kancayı seçtim çünkü kullanabileceğim en eski kancaydı. Kullanabilirsiniz, 'admin_init'ancak bu kanca çok daha sonra çalıştırılır (3. kanca çağrısı - 3. kanca çağrısı), neden WordPress'in gerekenden daha fazla atma çalışması yapmasına izin verdiniz? ( Hangi kancanın kullanılacağını bulmak için Alet Kancaları eklentisini kullandım.)

URL /wp-admin/tools.phpadresimin, $pagenowdeğişkeni inceleyerek başladığından emin olmak için kontrol ettiğimde , bunu doğrularım current_user_can('download_csv')ve geçerse o $_GET['download']zaman içerip içermediğini görmek için test ederim data.csv; eğer evet ise pratikte eskisi gibi aynı kodu kullanıyoruz. Ayrıca , önceki örnekte ,true,200yapılan çağrıdan çağrıyı kaldırdım header()çünkü burada WordPress bunun iyi bir URL olduğunu biliyor, bu yüzden henüz 404 durumunu ayarlamadı. İşte kodunuz:

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

Ve işte aktive edilmiş eklentinin ekran görüntüsü: (kaynak: mikeschinkel.com )Etkinleştirilmiş bir eklentiyi gösteren Eklenti Sayfasının ekran görüntüsü

Ve sonunda burada indirmeyi tetikleyen bir ekran görüntüsü: (kaynak: mikeschinkel.com )WordPress admin's Tools menüsünün bir seçeneğinden URL'ye göre dosya indirme ekran görüntüsü


Mike, yardımın için teşekkürler. Bu özelliği ile tek yakalamak, dosyanın arka uçtan indirilmesini istiyorum. Template_redirect arka uçta çalışmıyor gibi görünüyor ve eğer admin_init kullanmam gerekiyorsa ne kullanmam gerektiğini merak ediyorum. admin_init şimdi benim için çalışıyor gibi gözüküyor, en azından kısa vadede buna bağlı kalabilirim. Sadece birkaç kişinin kullanacağı küçük bir özellik.
Dave Morris

@Dave Morris - "Arka uç" ile ne demek istediğinizi tanımlayabilir misiniz ? Sunucuda mı demek istiyorsun? Evet ise, 'template_redirect'kesinlikle sunucuda çalışır. Olmazsa, tamamen kafam karıştı; Endişeyi açıklayabilir misin? Şimdiden teşekkürler.
MikeSchinkel

@Dave: Yönetici alanını "arka uç" ile kastediyorsanız, bu hala işe yarayacaktır. İndirme URL'si var /downloads/data.csvolmayan bir dosya ile başlar, böylece WordPress "ön uç" bu isteği yerine getirir ve sonunda ulaşır template-redirect. Yönetici alanında, bu ön URL’yi gösteren bir bağlantı oluşturursunuz. (Bu yolla, yönetici giriş korumasını ücretsiz alamayacağınız söylenmelidir - URL’nin dosyayı indirebileceğini bilen herkes, ancak bunu düzeltmenin kolay bir yolu var mıdır?)
Jan Fabry

@Jan Fabry - Ah, şimdi anlıyorum. By "arka uç" haklı, yönetici içinden geliyordu? Bu işlevi current_user_can()yukarıdaki kodla kullanabilir veya başka bir yaklaşım izleyebilir . Bu yorumdan sonra cevabımı güncelleyeceğim.
MikeSchinkel

Evet, özür dilerim, bu siteden e-posta uyarıları alamıyorum, bu yüzden yanıtlamadaki gecikmemi açıklıyor. Gerçekten "arka uç" dediğimde WordPress'in yönetim alanından bahsediyordum. Bunun için üzgünüm. Template_redirect'i kullanmayı deneyeceğim ve ne olacağını göreceğim. Teşekkürler! ~ Dave
Dave Morris

3

CSV'ye dışa aktarmak için bir başka kullanışlı eklenti. bazıları için yararlı olabilir

    <?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 veya load- (sayfa) Hook çalışıyor gibi görünüyor, WordPress bu durumda başlık ayarlanmadı. kullanıyorum load- (sayfa) bir yönetim menüsü sayfa yüklendiğinde o çalıştığı için Kanca. Komut dosyanızı belirli bir sayfa için yükleyebilirsiniz.

Kontrol edebilirsin Yükü (sayfa) WordPress Kodeksinde Kanca

Eğer kullanıyorsanız admin_init Kanca markasını emin etmek Nonce doğrulamak kullanarak check_admin_referer çıktı üretmesi indirme dosyasını alacak belki koşulu geçmesi veya başka senaryo.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.