【WordPress初心者卒業!】欲しい情報をデータベースから取得する方法


【WordPress初心者卒業!】欲しい情報をデータベースから取得する方法

WordPress 経験者なら誰しも思う、「このプラグインいいけど、もうチョットこんな機能欲しいな」という "わがままマインド"。

今回はあえて自分のわがままを実現すべく、 WordPress のデータベースに接続して”データ”を操作。

他のみんなが扱わないようなデータを扱えるようになったら、すごく気持ちいいですよ。

目次
  1. 【WordPress初心者卒業!】欲しい情報をデータベースから取得する方法
  2. 本稿の目標:プラグイン「Stripe Payments」に商品カテゴリ機能を追加
  3. WordPressのデータ操作方法
  4. WordPressのデータベースと接続
  5. 商品情報を取得
  6. WordPressに商品カテゴリをセット
  7. WordPressのデータベースを扱う様子の動画
  8. まとめ

【WordPress初心者卒業!】欲しい情報をデータベースから取得する方法

本稿の目標:プラグイン「Stripe Payments」に商品カテゴリ機能を追加

image

上図のコードを今確認する

<?php
/**
 * Template Name: item-list-stripe
 * Template Post Type: page

 *
 * @link https://developer.wordpress.org/themes/basics/template-hierarchy/
 *
 * @package WordPress
 * @subpackage Twenty_Twenty
 * @since Twenty Twenty 1.0
 */

get_header();

//$results = $wpdb->get_results( 'SELECT * FROM wp_posts' );
//1 var_dump($results[0]);
//Comment
?>

<main id="site-content" role="main">

    <?php
        get_template_part( 'template-parts/content', get_post_type() );
    ?>
    <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
    <script>
    $(document).ready(function(){
        $("select").change(function(){
            $(this).find("option:selected").each(function(){
                var optionValue = $(this).attr("value");
                if(optionValue){
                    $(".box").not("." + optionValue).hide();
                    $("." + optionValue).show();
                } else{
                    $(".box").hide();
                }
            });
        }).change();
    });
    </script>
    <style>
        .grid{
            display: grid;
            grid-template-columns: auto auto;
            background-color: #2196F3;
            padding: 10px;
        }
        .box {
          background-color: rgba(255, 255, 255, 0.8);
          border: 1px solid rgba(0, 0, 0, 0.8);
          padding: 20px;
          font-size: 30px;
          text-align: center;
        }
        svg, img, embed, object {
            display: block;
            margin: 0 auto;
            height: 40vh;
        }
        @media (min-width: 700px)
            .singular .entry-header {
            /* padding: 8rem 0; */
        }
        .singular .entry-header {
            background-color: #fff;
            /* padding: 4rem 0; */
        }
        .post-inner thin{
            display:none;
        }
    </style>

    <header class="archive-header has-text-align-center header-footer-group">
        <!-- <div class="archive-header-inner section-inner medium"> -->
            <h1 class="archive-title">
            <?php
                global $wpdb;
                $item_count = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->posts WHERE post_type='asp-products' AND post_status='publish'" );
                echo "<p>商品数: {$item_count}</p>";
            ?>
            </h1>
            <div>
                <select>
                    <option>カテゴリー選択</option>
                    <option value="category-service" selected>サービス</option>
                    <option value="category-omiyage">お土産</option>
                </select>
            </div>
            <?php
                echo '<hr class="post-separator styled-separator is-style-wide section-inner" aria-hidden="true" />';
                $item_ID = $wpdb->get_col( "SELECT ID FROM $wpdb->posts WHERE post_type='asp-products' AND post_status='publish'");
                //echo gettype($item_ID);
                //echo var_dump($item_ID); //配列の中身
                $items = $wpdb->get_col( "SELECT post_title FROM $wpdb->posts WHERE post_type='asp-products' AND post_status='publish'");
                $thumbnail = $wpdb->get_col( "SELECT meta_value FROM $wpdb->postmeta WHERE meta_key='asp_product_thumbnail'");
                $item_price = $wpdb->get_col( "SELECT meta_value FROM $wpdb->postmeta WHERE meta_key='asp_product_price'");

                //$mypost = $wpdb->get_row( "SELECT * FROM $wpdb->posts WHERE ID = 1" );
                //echo $mypost->post_title;

                //$item_category = $wpdb->get_row("SELECT * FROM $wpdb->postmeta WHERE ID=$item_ID");
                //echo $item_category->meta_value;

                //× $category = $wpdb->get_row("SELECT * FROM $wpdb->postmeta WHERE meta_value = 【マイサービス】イクメン実体験のメソッド公開、後悔のしない家族づくりへ");
                //× echo $category;

                echo '<div class="grid">';

                $x = 0;
                foreach ( $items as $item ) {
                    //echo 'ID: '.$item_ID[$x];
                    //$item_category = $wpdb->get_row("SELECT * FROM $wpdb->postmeta WHERE post_id=$item_ID[$x]");
                    $item_category = $wpdb->get_col("SELECT meta_value FROM $wpdb->postmeta WHERE post_id=$item_ID[$x] AND meta_key='asp_product_description'");
                    //echo '--'.$item_category[0];
                    if(strpos($item_category[0],'サービス') == true){
                        echo '<div class="category-service box">';
                        echo '<img src="'.$thumbnail[$x].'">';
                        echo '<a href="https://codecamp.o-namae.com/asp-products/'.$item.'">'.$item.'</a><br>';
                        echo '<p>価格: '.$item_price[$x].'円</p>';
                        echo '<small>カテゴリ: サービス</small>';
                        echo '</div>';
                    } elseif(strpos($item_category[0],'ワールド') == true){
                        echo '<div class="category-omiyage box">';
                        echo '<img src="'.$thumbnail[$x].'">';
                        echo '<a href="https://codecamp.o-namae.com/asp-products/'.$item.'">'.$item.'</a><br>';
                        echo '<p>価格: '.$item_price[$x].'円</p>';
                        echo '<small>カテゴリ: 世界</small>';
                        echo '</div>';
                    }
                    $x++;
                }
                echo '</div>';

            ?>
            <?php get_template_part( 'template-parts/pagination' ); ?>

</main><!-- #site-content -->

<?php get_template_part( 'template-parts/footer-menus-widgets' ); ?>

<?php get_footer(); ?>

GitHub

SAMPLE PAGE

先日 WordPress に課金機能を実装する記事でご紹介させていただいたプラグインの「Stripe Payments」。 その際デフォルトの商品一覧ページとは別に”オリジナルの商品一覧”を紹介させて頂きました。

今回はこの”商品一覧”を表示する処理フローを少し詳しくご紹介していきます。

チョット退屈に感じるかもしれませんが、WordPressをもっと活用したいと考えている方には参考になると思いますので、頑張ってご自身でも実践してみてください。 また前回実装できなかった”商品カテゴリ”機能も搭載してみましたよ。

WordPressのデータ操作方法

image

今回はデータベースにアクセスしてデータを活用しようと思っていますが、それ以外にもいくつかの方法で WordPress のデータを活用する方法があります。

  • WordPress の API
  • プラグイン
  • WordPressのクラス: WP_Query()
  • データベース

まず WordPress の API、こちらは投稿情報などを JSON 形式で取得する機能。APIは、様々なデータ処理に活用できますが、 Stripe プラグインは独自のデータベースを生成します。そのため WordPress API で対応できるか不明なので ❌。

プラグインを利用してデータベースの情報も操作できますが、複雑な処理は無理そうなので ❌。 WP_Query() は、データベースからデータ取得後に処理する機能なので、処理機能は基本的に WordPress 本体に付随データなので ❌。

結果的に柔軟にデータを活用しようと思うと「データベース」となるわけですね。

WordPressのデータベースと接続

【事前準備】

  • WordPress をテキストエディタで編集できるようにセット
  • WordPress に Stripe Payments をセットし、適当に商品登録しておく
  • ブラウザで phpMyAdmin を開く

WordPressに決済機能のStripeを装備する様子: YouTube

今回はセットアップが簡単なレンタルサーバーに WordPress を用意し、 FTP で自分のパソコンと接続し、プログラミングしていきます。 まずは phpMyAdmin から現在のデータベースの様子を眺めてみましょう。

image

ブログ投稿記事のデータが格納されるテーブル: wp_posts に商品情報が入っています。

image

商品のサムネイル画像や価格などはこちらの wp_postmeta に保存。

プラグイン Stripe Payments は、既存の投稿用データベース・テーブルの(wp_posts)に新しく商品用の列(カラム)を作り、商品価格や画像情報はテーブル(wp_postmeta)に書き込み。

まずは試しに現在の商品数を確認してみましょう。WordPress プログラム内の wp-content/themes/twentytwenty/ フォルダ内に一つ PHP ファイルを作って、wp-content/themes/twentytwenty/singular.php のコードをコピペ。そして以下のコードを <main> 内に追加(参考動画:WordPress内に新規ファイル作成する様子)。

<?php
    global $wpdb;
    $item_count = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->posts WHERE post_type='asp-products' AND post_status='publish'" );
    echo "<p>商品数: {$item_count}</p>";
?>

そして WordPress管理画面の固定ページ作成画面で、テンプレートを上記の PHP ファイルを選択、公開。 ブラウザで固定ページを開いてみると、商品点数が表示されると思います。

image

上図のコードを今確認する

<?php
/**
 * Template Name: item-list-stripe0
 * Template Post Type: page
 *
 * @link https://developer.wordpress.org/themes/basics/template-hierarchy/
 *
 * @package WordPress
 * @subpackage Twenty_Twenty
 * @since Twenty Twenty 1.0
 */

get_header();

global $wpdb;
//$results = $wpdb->get_results( 'SELECT * FROM wp_posts' );
//1 var_dump($results[0]);
//Comment
?>

<main id="site-content" role="main">

    <?php
        get_template_part( 'template-parts/content', get_post_type() );
    ?>

    <header class="archive-header has-text-align-center header-footer-group">
        <div class="archive-header-inner section-inner medium">
            <h1 class="archive-title">
            <?php
                $item_count = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->posts WHERE post_type='asp-products' AND post_status='publish'" );
                echo "<p>商品数: {$item_count}</p>";
            ?>
            </h1>
            <?php get_template_part( 'template-parts/pagination' ); ?>

</main><!-- #site-content -->

<?php get_template_part( 'template-parts/footer-menus-widgets' ); ?>

<?php get_footer(); ?>

この商品点数が取得できた原理は以下の通り。

まず追加コードの global $wpdb; で、 WordPressと接続しているデータベースとのやりとりを許可。そして 2行目の $wpdb->get_var() でデータベース内の値をとることを宣言。尚、 get_var() 意外に、行データを取得する get_row() や 列データを取得する get_culum() などが他にもあり(公式ドキュメント)。

そして SELECT COUNT(*) とすることで”足し算”を宣言し、足す項目は FROM 以下で宣言。今回取得する項目は、投稿内容が商品(post_type='asp-products')で公開済みのデータ(post_status='publish')を対象に。そして取得したデータを変数: $item_count に格納し、 echo で出力処理。

最初は慣れないですが、一度データベースからデータを取ってこれたら、結構嬉しいと思います。今回は Stripe のプラグインで試していますが、”投稿”に関するデータやコメントなども同じ要領で取得でき、 WordPress 上のデータを柔軟に使えるようになりますね。

商品情報を取得

さあデータベースに接続できましたので、次は具体的なデータ処理までやっていきましょう。

image

上図のコードを今確認する

<?php
/**
 * Template Name: item-list-stripe1
 * Template Post Type: page
 *
 * @link https://developer.wordpress.org/themes/basics/template-hierarchy/
 *
 * @package WordPress
 * @subpackage Twenty_Twenty
 * @since Twenty Twenty 1.0
 */

get_header();

global $wpdb;
//$results = $wpdb->get_results( 'SELECT * FROM wp_posts' );
//1 var_dump($results[0]);
//Comment
?>

<main id="site-content" role="main">

    <?php
        get_template_part( 'template-parts/content', get_post_type() );
    ?>

    <header class="archive-header has-text-align-center header-footer-group">
        <div class="archive-header-inner section-inner medium">
            <h1 class="archive-title">
            <?php
                $item_count = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->posts WHERE post_type='asp-products' AND post_status='publish'" );
                echo "<p>商品数: {$item_count}</p>";
            ?>
            </h1>
            <?php
                echo '<hr class="post-separator styled-separator is-style-wide section-inner" aria-hidden="true" />';
                $items = $wpdb->get_col( "SELECT post_title FROM $wpdb->posts WHERE post_type='asp-products' AND post_status='publish'");
                echo gettype($items);
                echo var_dump($items);

                foreach ( $items as $item ) {
                    echo '<ul><li>';
                    echo '<a href="https://codecamp.o-namae.com/asp-products/'.$item.'">'.$item.'</a>';
                    echo '</li></ul>';
                  }

            ?>

            <?php get_template_part( 'template-parts/pagination' ); ?>

            </main><!-- #site-content -->

            <?php get_template_part( 'template-parts/footer-menus-widgets' ); ?>

            <?php get_footer(); ?>

まずは登録済みの商品データを取得。要領としては先ほどの「商品数」の時と同じですが、今度は $wpdb->get_var() ではなく $wpdb->get_col() を利用。 そして SELECT post_title とすることで全商品のタイトル一覧を取ってきてくれます。

データベースから取得したデータは、目には見えないのでどんな形・内容をしているのかわかりません。そこでまずは gettype() を実行して、データ型を確認。するとブラウザ上に array つまり”配列”と表示。そしてその配列の中にどんなデータが入っているかは、 var_dump() で確認可能。

さらに配列内のデータを一つずつ取り出すのに便利な foreach() を使えば、データベース内に保存されている商品一覧のタイトル、つまり商品名リストを取り出すことができます。同じ要領で商品名以外に、サムネイル画像や投稿内容を取得できますね。

ここまでできれば通常の WordPress のデータを使って、様々な自分好みの処理ができるようになるでしょう。

WordPressに商品カテゴリをセット

商用プラグインの WooCommerce などを使えばいいことかもしれませんが、今回はせっかく導入したプラグイン Stripe Payments を使い尽くすべく、プラグイン Stripe Payments に標準搭載されていない”カテゴリ機能”を追加してみたいと思います。

この作成プロセスは決して Stripe Payments のみに役立つというわけではなく、 WordPress の様々なプラグインに対して有効になってくると思いますので、ご参考いただければ幸いです。尚、これから紹介するプログラムは公式ドキュメント等があるものではなく”自作”です。ご自身の責任においてご利用くださいね。

image

上図のコードを今確認する

<?php
/**
 * Template Name: item-list-stripe
 * Template Post Type: page

 *
 * @link https://developer.wordpress.org/themes/basics/template-hierarchy/
 *
 * @package WordPress
 * @subpackage Twenty_Twenty
 * @since Twenty Twenty 1.0
 */

get_header();

//$results = $wpdb->get_results( 'SELECT * FROM wp_posts' );
//1 var_dump($results[0]);
//Comment
?>

<main id="site-content" role="main">

    <?php
        get_template_part( 'template-parts/content', get_post_type() );
    ?>
    <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
    <script>
    $(document).ready(function(){
        $("select").change(function(){
            $(this).find("option:selected").each(function(){
                var optionValue = $(this).attr("value");
                if(optionValue){
                    $(".box").not("." + optionValue).hide();
                    $("." + optionValue).show();
                } else{
                    $(".box").hide();
                }
            });
        }).change();
    });
    </script>
    <style>
        .grid{
            display: grid;
            grid-template-columns: auto auto;
            background-color: #2196F3;
            padding: 10px;
        }
        .box {
          background-color: rgba(255, 255, 255, 0.8);
          border: 1px solid rgba(0, 0, 0, 0.8);
          padding: 20px;
          font-size: 30px;
          text-align: center;
        }
        svg, img, embed, object {
            display: block;
            margin: 0 auto;
            height: 40vh;
        }
        @media (min-width: 700px)
            .singular .entry-header {
            /* padding: 8rem 0; */
        }
        .singular .entry-header {
            background-color: #fff;
            /* padding: 4rem 0; */
        }
        .post-inner thin{
            display:none;
        }
    </style>

    <header class="archive-header has-text-align-center header-footer-group">
        <!-- <div class="archive-header-inner section-inner medium"> -->
            <h1 class="archive-title">
            <?php
                global $wpdb;
                $item_count = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->posts WHERE post_type='asp-products' AND post_status='publish'" );
                echo "<p>商品数: {$item_count}</p>";
            ?>
            </h1>
            <div>
                <select>
                    <option>カテゴリー選択</option>
                    <option value="category-service" selected>サービス</option>
                    <option value="category-omiyage">お土産</option>
                </select>
            </div>
            <?php
                echo '<hr class="post-separator styled-separator is-style-wide section-inner" aria-hidden="true" />';
                $item_ID = $wpdb->get_col( "SELECT ID FROM $wpdb->posts WHERE post_type='asp-products' AND post_status='publish'");
                //echo gettype($item_ID);
                //echo var_dump($item_ID); //配列の中身
                $items = $wpdb->get_col( "SELECT post_title FROM $wpdb->posts WHERE post_type='asp-products' AND post_status='publish'");
                $thumbnail = $wpdb->get_col( "SELECT meta_value FROM $wpdb->postmeta WHERE meta_key='asp_product_thumbnail'");
                $item_price = $wpdb->get_col( "SELECT meta_value FROM $wpdb->postmeta WHERE meta_key='asp_product_price'");

                //$mypost = $wpdb->get_row( "SELECT * FROM $wpdb->posts WHERE ID = 1" );
                //echo $mypost->post_title;

                //$item_category = $wpdb->get_row("SELECT * FROM $wpdb->postmeta WHERE ID=$item_ID");
                //echo $item_category->meta_value;

                //× $category = $wpdb->get_row("SELECT * FROM $wpdb->postmeta WHERE meta_value = 【マイサービス】イクメン実体験のメソッド公開、後悔のしない家族づくりへ");
                //× echo $category;

                echo '<div class="grid">';

                $x = 0;
                foreach ( $items as $item ) {
                    //echo 'ID: '.$item_ID[$x];
                    //$item_category = $wpdb->get_row("SELECT * FROM $wpdb->postmeta WHERE post_id=$item_ID[$x]");
                    $item_category = $wpdb->get_col("SELECT meta_value FROM $wpdb->postmeta WHERE post_id=$item_ID[$x] AND meta_key='asp_product_description'");
                    //echo '--'.$item_category[0];
                    if(strpos($item_category[0],'サービス') == true){
                        echo '<div class="category-service box">';
                        echo '<img src="'.$thumbnail[$x].'">';
                        echo '<a href="https://codecamp.o-namae.com/asp-products/'.$item.'">'.$item.'</a><br>';
                        echo '<p>価格: '.$item_price[$x].'円</p>';
                        echo '<small>カテゴリ: サービス</small>';
                        echo '</div>';
                    } elseif(strpos($item_category[0],'ワールド') == true){
                        echo '<div class="category-omiyage box">';
                        echo '<img src="'.$thumbnail[$x].'">';
                        echo '<a href="https://codecamp.o-namae.com/asp-products/'.$item.'">'.$item.'</a><br>';
                        echo '<p>価格: '.$item_price[$x].'円</p>';
                        echo '<small>カテゴリ: 世界</small>';
                        echo '</div>';
                    }
                    $x++;
                }
                echo '</div>';

            ?>
            <?php get_template_part( 'template-parts/pagination' ); ?>

</main><!-- #site-content -->

<?php get_template_part( 'template-parts/footer-menus-widgets' ); ?>

<?php get_footer(); ?>

まず”商品カテゴリ”ということですが、デフォルトの Stripe Payments には”カテゴリ”という項目が存在しません。そのため自分で”カテゴリ”を作成するか、既存のプラグイン機能を使って”カテゴリ相当”のモノを作る必要があります。

前者の「カテゴリを作成」は、プラグインの更新を考えるとややリスキー。よって今回は”カテゴリ相当”のモノを作って対処してみました。

【カテゴリ相当を使った場合の処理フロー】

まず今回のような ”ない機能” を新たに作る場合、重要なことは ”完成イメージ” を持つこと。楽天市場や ヤフオク! などで見かける ”セレクト” 機能を使うとカテゴリを管理しやすそうなので、上図左のように選択項目のカテゴリの商品一覧を表示することをゴールとしました。

そして肝心のカテゴリ振り分け処理、こちらの思考プロセスはいくつかパターンがあると思いますが、今回は「どうすれば商品データにカテゴリを追加できるか」という点からスタート。 まず商品登録画面をよく眺め、商品のレイアウトにあまり影響しなさそうな「簡単な説明」という枠に注目(上図真ん中)。こちらの入力データはデータベース上では、テーブル: wp_postmeta 内の meta_value という項目にデータが反映されています。

つまり商品登録の際に特定のキーワードを「簡単な説明」に入力し、それをカテゴリとして扱い、”商品カテゴリ:サービス”が欲しい時は meta_value 内の「サービス」を含む商品情報をピックアプできれば良さそう。 要は検索機能に似たプロセスですね。

次にカテゴリ・マーキングできた商品情報を適切に表示するためには、 HTML の <select> を使うと手っ取り早そう。 PHP 側で選択項目のカテゴリ商品のみを出力する方法もあるかもしれませんが、 JavaScript(jQuery)の方が簡単そうです。

<select> タグで選択中の項目のみを表示し、あとの非選択中のカテゴリ商品は非表示にすれば「カテゴリ機能」として機能してくれそうです。

文量的にコードの解説まではできませんので、ご興味ある方は上記コードをご参考の上、ご自身でもアレンジしてみてください。

WordPressのデータベースを扱う様子の動画

本稿と合わせてご参考ください。また本稿でご紹介した Stripe Payments へのカテゴリ搭載する様子を下記動画にまとめました。

一流デザイナーのスキルが身に付く

無料カウンセリングはこちら

まとめ

今回 WordPress でプラグインのデータを使ってカテゴリ機能を追加する、ということを行いましたが、PHP と WordPress、データベースと HTML、 それから JavaScript とチョットした事なのにずいぶんたくさんの処理工程が登場したように感じるかもしれません。

しかしこれでも Stripe の決済部分はプラグイン:Stripe Payments に一任していますので、フレームワークベースの開発に比べると楽な方かもしれません。(逆にフレームワークと API が使えると、プラグインの制約、WordPressの制約を気にする事なく、もう少し自由に開発できます。)

「データベース、これは一人では無理だな、諦めよう...」「WordPressはプラグインをガッツリ使えばそれでいい...」 とお考えの方もいらっしゃるかもしれません。ですが、エンジニアやプログラマーを目指したいという気持ちが少しでもあるのなら、自分に立ち向かってチョットがんばってみませんか?

CodeCamp では難しいデータベースや PHP、 JavaScript も基礎から包括的にサポートします。 まずは無料体験から、自分の理想とする未来に挑戦してみませんか?


関連記事

オシママサラ
この記事を書いた人
オシママサラ
まずは7日間お試し!人気プログラミング講座を無料公開中
オンライン・プログラミングレッスンNo.1のCodeCamp