0

私は長い間 PHP でコーディングしてきましたが、現在、最初の Wordpress プラグインを作成しています。プラグインの目標は次のとおりです。

  • 公開ページにフォームを表示して、サイト訪問者から簡単なデータ (名/姓など) を収集します。
  • 管理者がデータをエクスポートする方法を提供する

アクティベーション時にテーブルを正常に作成するプラグインと、送信されたデータをデータベースに正常に保存するフォームを提供するショートコードがあります。

バックエンドには、提出に関するいくつかの統計を現在表示しているダッシュボード ウィジェットがあります。私の最後のタスクは、それらの統計を CSV にエクスポートするボタンを提供することです。ここで困惑しています。WPの世界でこれを処理する方法がわかりません...以前は、エクスポートを実行し、CSV文字列をページにエコーするページへの新しいウィンドウを開くボタンがありました。バイナリファイルなので、ダウンロードされます。WP では、どうすればこれを達成できますか? プラグイン ディレクトリに PHP スクリプトを配置し、ウィジェットでそのページを開く必要がありますか? もしそうなら、そのページはどのように $wpdb にアクセスしてデータ アクセスを処理しますか?

これが現在の私のコードです(ダッシュボードウィジェット部分のみ):

<?php
/*
Plugin meta details
 */
add_action('init', 'myplugin_buffer_start');
add_action('wp_footer', 'myplugin_buffer_end');

function myplugin_ob_callback($buffer) {
    // You can modify buffer here, and then return the updated code
    return $buffer;
}

/**
 * Action: init
 * Runs after WP has finished loading but before any headers are sent, user is already authenticated at this point
 * Good for intercepting $_POST/$_GET
 */
function myplugin_buffer_start() 
{ 
    ob_start("myplugin_ob_callback"); 
}

/**
 * Action wp_footer
 * Triggered near the </body> tag of the user's template by the wp_footer() function.
 */
function myplugin_buffer_end() 
{ 
    ob_end_flush(); 
}


/****************************************************************
 *  Stats Dashboard Widgets
 ***************************************************************/
function myplugin_displaytestFormWidget_process()
{
    $errors = array();

    if ( 'POST' == $_SERVER['REQUEST_METHOD'] && isset ( $_POST['myplugin_export_button'] ))
    {
        ob_end_clean(); // erase the output buffer and turn off buffering...blow away all the markup/content from the buffer up to this point

        global $wpdb;
        $tableName = $wpdb->prefix . "myplugin_test_form";
        $qry = "select Name, Date from $tableName order by Date desc";

        //ob_start();  when I uncomment this, it works!
        $result = $wpdb->get_results($qry, ARRAY_A);
        if ($wpdb->num_rows)
        {
            $date = new DateTime();
            $ts = $date->format("Y-m-d-G-i-s");
            $filename = "myCsvFile-$ts.csv";
            header( 'Content-Type: text/csv' );
            header( 'Content-Disposition: attachment;filename='.$filename);

            $fp = fopen('php://output', 'w');
            //$headrow = $result[0];
            //fputcsv($fp, array_keys($headrow));
            foreach ($result as $data) {
                fputcsv($fp, $data);
            }
            fclose($fp);

            //when I uncomment these lines along with adding ob_start above, it works
            //$contLength = ob_get_length();
            //header( 'Content-Length: '.$contLength);
        }
    }

    return myplugin_displaytestFormWidget();
}   

function myplugin_displaytestFormWidget()
{
    global $wpdb;
    $tableName = $wpdb->prefix . "myplugin_test_form";

    $submissionCount = $wpdb->get_var("select count(Id) from $tableName");
?>
    <div><strong>Last entry: </strong>John Q. test (May 5, 2013)</div>
    <div><strong>Total submissions: </strong> <?php echo $submissionCount ?></div>

    <form id="myplugin_test_export_widget" method="post" action="">
        <input type="submit" name="myplugin_export_button" value="Export All" />
    </form>
<?php
}

function myplugin_addDashboardWidgets()
{
    // widget_id, widget_name, callback, control_callback
    wp_add_dashboard_widget(
        'test-form-widget', 
        'test Form Submissions', 
        'myplugin_displaytestFormWidget_process'
    );  
}

/****************************************************************
 *  Hooks
 ***************************************************************/
//add_action('widgets_init', 'simple_widget_init');
add_action('wp_dashboard_setup', 'myplugin_addDashboardWidgets' ); 

// This shortcode will inject the form onto a page
add_shortcode('test-form', 'myplugin_displaytestForm_process');

register_activation_hook(__FILE__, 'myplugin_test_form_activate');

myplugin_displayTestFormWidget関数でフォームを表示していることがわかりますが、ボタンをどうすればすべてジャイブになるかわかりません。

ウィジェット出力のスクリーンショット

誰でも手伝ってもらえますか?

4

2 に答える 2

2

まず、プラグインに次のコードを追加します

add_action('init', 'buffer_start');
add_action('wp_footer', 'buffer_end');

function callback($buffer) {
    // You can modify buffer here, and then return the updated code
    return $buffer;
}
function buffer_start() { ob_start("callback"); }
function buffer_end() { ob_end_flush(); }

プラグインのメタ情報の直後の一番上

/**
 * @package Word Generator
 * @version 1.0
 * ...
 */
 // here goes the code given above, it'll solve the header sent error problem

そして、次のコードはcsvファイルをダンプします

if ( 'POST' == $_SERVER['REQUEST_METHOD'] && isset ( $_POST['myplugin_export_button'] ))
{
    // Somehow, perform the export 
    ob_clean();
    global $wpdb;
    $qry = 'your query';
    $result = $wpdb->get_results($qry, ARRAY_A);
    if ($wpdb->num_rows){
        $date = new DateTime();
        $ts = $date->format("Y-m-d-G-i-s");
        $filename = "myCsvFile-$ts.csv";
        header( 'Content-Type: text/csv' );
        header( 'Content-Disposition: attachment;filename='.$filename);

        $fp = fopen('php://output', 'w');
        $headrow = $result[0];
        fputcsv($fp, array_keys($headrow));
        foreach ($result as $data) {
            fputcsv($fp, $data);
        }
        fclose($fp);
        $contLength = ob_get_length();
        header( 'Content-Length: '.$contLength);
        exit();
    }
}
于 2013-05-23T22:30:41.620 に答える
0

少し前に開発した別のプラグインに同様の機能を実装しました。それがベスト プラクティスであるとは言いませんが (この場合にそのようなことがあるかどうかは 100% 確信が持てません)、当時の私にとってはクリーンで信頼できるソリューションのように思えました。

中断したところから再開して、myplugin_displayTestFormWidget_process関数内に実際のコードと疑似コードをいくつか入れてみましょう。

if ( 'POST' == $_SERVER['REQUEST_METHOD'] && isset ( $_POST['myplugin_export_button'] ))
{
    // clear out the buffer
    ob_clean();
    // get the $wpdb variable into scope so you may use it
    global $wpdb;

    // define some filename using a timestamp maybe
    // $csv_file_name = 'export_' . date('Ymd') . '.csv';

    // get the results of your query
    $result = $wpdb->get_results("SELECT * FROM your_table");

    // loop your results and build your csv file
    foreach($result as $row){
        // put your csv data into something like $csv_string or whatever
    }

    header("Content-type: text/x-csv");
    header("Content-Transfer-Encoding: binary");
    header("Content-Disposition: attachment; filename=".$csv_file_name);
    header("Pragma: no-cache");
    header("Expires: 0");

    echo $csv_string;
    exit;
}

あなたは PHP にかなり慣れているとおっしゃっていたので、これを実現するための PHP の側面については深く掘り下げませんでした。

お役に立てば幸いです。楽しんでください。

于 2013-05-23T20:40:44.103 に答える