（中断...）WordPressによる顧客管理システム2016

HTMLもPHPもWordPressもロクにわかってないローカルアプリ屋が顧客管理システムに奮闘する。
冗長な表現があると思うけど、逆に言うとわかってない人もそれなりに追えると思う。

#参考ページ
・[ホームページだけじゃない！管理システムとしてのWordPress](http://tech.hi-works.com/webcreative/wordpress/769) ←これいろいろ古いなぁ...

#クライアントが抱える問題点及び要望
・Facebook等でややアナログに通販のオーダーを受けてから、[クロネコB2Web](http://www.kuronekoyamato.co.jp/newb2/newb2.html) を使って「送り状」を発行し、管理。一時期に200件超の入力が集中発生した結果、未発送トラブルに見舞われた模様。
というのも、クロネコB2は「伝票発行したものの実は送ってない」という「カラ伝票」の状態というのがあって、ログを見てみたらそのカラ伝票がたくさんあった...。シチュエーションとしては伝票だけ先に用意したけど送ろうとした日に、送付オペレーションが限界に来たりして "その日は送らなかった" という「小さなカラ伝票ゴミ」がつもりつもって混乱を引き起こしたのだと思われる。

・こっちが全部手当するんじゃなくて、Webページで顧客自身が、「去年どこにいくつ送ったっけ？」というのを思い出しながらオーダーさせ、こっちはCSVにまとめてオーダーを出力してクロネコB2のアップローダーを使って送り状を発行させるところまでやりたい。

#おおまかな仕様
・顧客が自分で送付先住所などを入力して注文する
・顧客が自分で注文済み明細を照会出来る
・旅館側がクロネコのドライバーに商品を渡したときにエビデンス（写真）を撮り、画像をアップロードする
・旅館側はエビデンスの登録されていない未発送リストに対する「クロネコB2フォーマットのCSV」を出力することができる
・顧客も旅館のスタッフも出先などでも確認出来る
・請求書を発行できる
・未払いフラグをつけて、未払い者に対して督促メールを送ることができる

#行動開始
WordPress自体の「テーマ」はなんでもいいんじゃないかなぁ。どうせ改造するし...ってことで

#子テーマの作成
[WordPressテーマのカスタマイズで子テーマを使うべき理由、使い方など](http://nelog.jp/wordpress-child-theme)
「テーマ」は自動的にアップデートされて、ほどこしたカスタマイズはなかったことにされるようだ。子テーマは、カスタマイズ部分だけを書けばいいので、むしろ管理しやすくなる模様。
１．子テーマのフォルダを作る
２．子テーマに必要なファイルを作る
３．親テーマを継承するためのコードを書く

```text:ターミナル１（VPS接続用）：コマンドメモ
（WordPressを入れた場所）$ cd ../../var/www/html/wp-content/themes
（フォルダを作成）$ mkdir twentyfifteen-child
（フォルダを作成した場所）$ cd ./twentyfifteen-child
（Viで開く）$ vi functions.php #ファイルがなければ新規作成してくれる
（Viで開く）$ vi style.css
```

#伝票発行画面のレイアウトを変更
・[投稿画面から不要な機能を削除する](http://wpcj.net/976)
・[WordPress 管理画面の「WordPress のご利用ありがとうございます。」を非表示にする](http://www.gtbosh.com/word-press-admin-use-change/)
・[WordPressに「Yahoo・天気予報ブログパーツ」を設定する](https://mechalog.com/wordpress-yahooblogparts)
・[WordPressの functions.phpがある場所](http://blog.s-giken.net/75.html)
また [黒い画面](https://www.google.co.jp/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=%E9%BB%92%E3%81%84%E7%94%BB%E9%9D%A2) か　しょうがねぇなぁー

```text:ターミナル１（VPS接続用）：コマンドメモ
（いまどこ？）$ pwd
（WordPressを入れた場所）$ cd ../../var/www/html/wp-content/themes/twentyfifteen
（ここになにがありますか？）$ ls -l
（root権限にチェンジ）$ sudo -s
（Viで開く）$ vi functions.php
```

##functions.php
"子テーマの" functions.phpです。いまはこれでソース全量です。

```text:ターミナル１（VPS接続用）：コマンドメモ
<?php

/**
 * 親テーマのCSSも読んで下さい
 */
add_action( 'wp_enqueue_scripts', 'theme_enqueue_styles' );
function theme_enqueue_styles() {
    wp_enqueue_style( 'parent-style', get_template_directory_uri() . '/style.css' );
}

/**
 * 投稿画面から不要な機能を削除します。
 */
function remove_post_supports() {
    remove_post_type_support( 'post', 'editor' ); // 本文欄
}
add_action( 'init', 'remove_post_supports' );

/**
 * 「WordPress のご利用ありがとうございます。」を非表示にする
 */
add_filter('admin_footer_text', 'custom_admin_footer');

```

「本文欄」と管理画面のフッターの「WordPress のご利用ありがとうございます。」が消えた！
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/319c08df-8358-5bc7-c3aa-a3bcbcf59006.png)

#伝票一覧画面のレイアウトを変更
##index.php
このショットはまだ未加工。でもソースを見た限りでは、「content.php」ってファイルに依存して記事の子種をリスト表示するようだ。
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/587ca97f-f514-3fae-d3d2-6c8b5f069ca1.png)


つまりこういうこと（ここまでくるにも時間かかったな...でもだいぶphpの世界観に慣れてきた）
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/ef6ad576-da42-2696-2d09-5b47467ad46a.png)

##content.php
では、子種を見ていこう。
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/3aca2af1-3092-fb7b-2586-5257b24bf4ac.png)

この「if is_single()」の分岐は、子種を一覧表示しているときと、一覧のなかのうちのひとつをクリックして個別投稿を表示しているときの分岐らしい。つまり「個別投稿＝is_single()」のルートのところにテキトーに「あ」と打ち込んでみると
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/70f56a0a-2df7-8beb-e1a4-d584b44361ce.png)

１．個別投稿の画面に「あ」が出てきて
２．記事一覧には「あ」が出ない。
つまり「is_single()」はそういう判断命令らしい
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/7a32222c-23a6-1948-d8e0-8bf8cbad2384.png)


こうした

```php:ターミナル１（VPS接続用）：コマンドメモ
<?php
/**
 * The default template for displaying content
 *
 * Used for both single and index/archive/search.
 *
 * @package WordPress
 * @subpackage Twenty_Fifteen
 * @since Twenty Fifteen 1.0
 **/
?>

<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
        <?php
                // Post thumbnail.
                twentyfifteen_post_thumbnail();
        ?>

        <header class="entry-header">
                <?php
                        if ( is_single() ) :
                                the_title( '<h1 class="entry-title">', '</h1>' );
                        else :
                                the_title( sprintf( '<a href="%s" rel="bookmark">', esc_url( get_permalink() ) ), '</a>' );
                                edit_post_link( __( 'Edit', 'twentyfifteen' ), '<span class="edit-link">', '</span>' );
                        endif;
                ?>
        </header>

        <?php
                // Author bio.(記事作成ユーザーのプロフィール）
                if ( is_single() && get_the_author_meta( 'description' ) ) :
                        get_template_part( 'author-bio' );
                endif;
        ?>

</article><!-- #post-## -->
```

こうなった。なんか子種のワクがデケェェェーなー...！CSSかな...
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/b4a11943-c8de-cab6-fe40-d62a3947628c.png)

#CSSを編集する
##style.css
"子テーマの" style.cssです。いまはこれでソース全量です。

```php:ターミナル１（VPS接続用）：コマンドメモ
/*
 Theme Name:   Twenty Fifteen Child
 Template:     twentyfifteen
*/

/**
 * 3.0 Typography
 */
body,
button,
input,
select,
textarea {
	font-family: "Meiryo", serif;
}

/**
 * 12.0 Content
 */
.site-footer {
	padding: 1% 7.6923%;
}

/**
 * 12.1 Posts and pages
 */
.hentry {
	padding-top: 2%;
	padding-bottom: 1%;
}
.entry-content,
.entry-summary {
	padding: 0 7.6923% 1%;
}

/**
 * 15.0 Media Queries
 */
@media screen and (min-width: 38.75em)
.hentry + .hentry, .page-header + .hentry, .page-header + .page-content {
    margin-top: 1%;
}

/**
 * 15.1 Mobile Large 620px
 */
@media screen and (min-width: 38.75em) {
	
	.entry-summary {
		padding: 0 9.0909% 1%;
	}

	.site-footer {
		padding: 1% 7.6923%;
	}

	.site-main {
    		padding: 1% 0;
	}

	.hentry + .hentry, .page-header + .hentry, .page-header + 
	.page-content {
    		margin-top: 1%;
	}
}

/**
 * 15.4 Desktop Small 955px
 */
@media screen and (min-width: 59.6875em) {

	.site-main {
		padding: 1% 0;
	}

	.hentry {
		padding-top: 1%;
	}

	.page-header + .page-content {
		margin-top: 1%;
	}

        .site-footer {
                padding: 1% 7.6923%;
        }
}

```

#記事一覧のフッターを変更
[フッター「proudly powered by wordpress」を消す方法](https://wordpress999.info/wordpress-footer.html)
[ワードプレスのフッターをCopyright（C）に表示する方法](https://wordpress999.info/wordpress-copyright.html)
[フローティングメニューをフッターに表示する](http://www.nishi2002.com/14962.html)

![image](https://qiita-image-store.s3.amazonaws.com/0/94562/d856b6cb-1bdb-db93-830f-83712dee839e.png)

##footer.php
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/ef22168f-ea12-6f8d-a520-6982409302af.png)

```php:ターミナル１（VPS接続用）：コマンドメモ
<?php
/**
 * The template for displaying the footer
 *
 * Contains the closing of the "site-content" div and all content after.
 *
 * @package WordPress
 * @subpackage Twenty_Fifteen
 * @since Twenty Fifteen 1.0
 */
?>

	</div><!-- .site-content -->

	<footer id="colophon" class="site-footer" role="contentinfo">
		<div class="site-info" >
			<!-- クレジットの表記-->
			<a href="http://www.hidamaristyle.com/" target="_blank"><img src="http://xxx.xx.xx.xxx/wp-content/uploads/2016/10/3713f88b0d5bcfff013eb51b8832c609.png" >
		</div><!-- .site-info -->
	</footer><!-- .site-footer -->

</div><!-- .site -->

<?php wp_footer(); ?>

</body>
</html>
```

ということでこうなった
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/5c8b9c23-4301-0d03-09d5-8258f5b2ef3e.png)

#伝票一覧画面（子種一覧）にACFカスタムフィールドの値を表示する
[Advanced Custom Fieldsの出力](http://kotori-blog.com/wordpress/acf_output/)

content.phpのこれかな？
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/093500c2-c1fd-6886-ffea-72e5a6a72e1d.png)

おう！出たじゃん！むしろ管理画面の投稿一覧に出すよりラクだな！
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/b9dbec73-5447-fcad-650b-94a0c880f4f6.png)

じゃあ、「is_single()〜」のあたりをこんな感じでHTMLのテーブル組にしてーの、、
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/fd9b0dc2-645e-c52f-ad9f-3e31c36ce527.png)

##content.php

```php:ターミナル１（VPS接続用）：コマンドメモ
<?php
/**
 * The default template for displaying content
 *
 * Used for both single and index/archive/search.
 *
 * @package WordPress
 * @subpackage Twenty_Fifteen
 * @since Twenty Fifteen 1.0
 */
?>

<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
        <?php
                // Post thumbnail.
                twentyfifteen_post_thumbnail();
        ?>

        <header class="entry-header">

                <?php
                if ( is_single() ) :
                        the_title( '<h1 class="entry-title">', '</h1>' ); ?>
                        <table>
                        <thead><tr>
                                <th>出荷予定日</th>
                                <th>お届け先名</th></tr>
                        </thead>
                        <tbody><tr>
                                <td><?php the_field("003_SEND_YMD", $post_id); ?></td>
                                <td><?php the_field("012_DESTINATION_NAME", $post_id); ?></td></tr>
                        </tbody>
                        </table>

                <?php else: ?>
                        <table>
                        <thead><tr>
                                <th>伝票名</th>
                                <th>出荷予定日</th>
                                <th>お届け先名</th></tr>
                        </thead>
                        <tbody><tr>
                                <td><?php the_title( sprintf( '<a href="%s" rel="bookmark">', esc_url( get_permalink() ) ), '</a>' ); ?></td>
                                <td><?php the_field("003_SEND_YMD", $post_id); ?></td>
                                <td><?php the_field("012_DESTINATION_NAME", $post_id); ?></td></tr>
                        </tbody>
                        </table>
                <?php endif; ?>

        </header><!-- .entry-header -->

        </div><!-- .entry-content -->

        <?php
                // Author bio.
                if ( is_single() && get_the_author_meta( 'description' ) ) :
                        get_template_part( 'author-bio' );
                endif;
        ?>

</article><!-- #post-## -->

```

##style.css
"子テーマの" style.cssに<font color="red"><B>追記</B></font>

```php:ターミナル１（VPS接続用）：コマンドメモ
/**
 * 4.0 Elements
 */
table {
        margin: 0;
        border-width: 0;
}
th,td {
        border-width: 0;
}
```

#一度上空から観察
いいじゃん！あとは好きな項目があるかないかだからね。好きなだけ増減させればいい。
##子種一覧
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/80612172-e9c3-0b63-45ec-608c2fbd3c84.png)

##個別投稿
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/51848f7f-cf9c-8a06-4030-4a1f971092e6.png)

#伝票検索機能
[WordPressプラグイン『Search Everything』サイト内検索の範囲を選択する](http://miyabix.com/archives/8479)

これで、カスタムフィールドが検索できるようになりました。
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/d65616ab-38b5-e74b-4f7a-99d09e5145d9.png)

#画像用のカスタムフィールドを追加
画像用のカスタムフィールドを作ってみたけど「画像を追加する」が機能しない。どうやら権限が原因のようだ？（調査中）

![image](https://qiita-image-store.s3.amazonaws.com/0/94562/0686ae2e-1f79-0994-e24f-f0d0b9bec7c3.png)


#ユーザー管理機能
１．お客さんがログインして伝票を発行し、自分の発行した明細だけを見る
２．管理者がログインして全発行明細を見る
そういったユーザーの使い分け（管理）は<font color="red"><B>ダッシュボード（管理画面）へのログイン機能を使ってログインさせた直後に（ダッシュボードの画面にいかずに）ホームのページへ飛ばす</B></font>ことでおこなう。
普段から編集するときログインしまくってるでしょ？それの応用。
たしかにURLにアクセスするたんびにログイン求められて、これじゃなんか不自然じゃない？？ってちょっと思ってた、、。

##ログイン画面のロゴを変更する
[ログイン画面カスタマイズに便利なプラグイン「Custom Login Page Customizer」](http://www.nxworld.net/wordpress/wp-plugin-custom-login-page-customizer.html)

##顧客用ログイン時の管理画面をセットアップする
あぁ、このページはいいね
[WordPress管理画面を顧客用にカスタマイズする方法](http://htdsn.com/blog/archives/wordpress-admin-customize.html)
##WordPressバージョンの更新情報を非表示にする
##フッターのWordPressリンクを非表示にする
##[管理バー（上部）の「表示オプション」と「ヘルプ」を非表示にする](https://techmemo.biz/wordpress/hidden-options-help-link/)

```php:ターミナル１（VPS接続用）：コマンドメモ
// 「表示オプション」と「ヘルプ」を非表示にする
function my_admin_head(){
if (!current_user_can('level_10')) {
echo '<style type="text/css">#contextual-help-link-wrap,#screen-options-link-wrap{display:none;}</style>';
}
}
add_action('admin_head', 'my_admin_head');
```

##管理バー（上部）にログアウトを追加する
##ダッシュボード左側のメニューを非表示にする

```php:ターミナル１（VPS接続用）：コマンドメモ
// メニューを非表示にする
function remove_menus () { 
 if (!current_user_can('level_10')) { //level10以下のユーザーの場合メニューをunsetする
 remove_menu_page('wpcf7'); //Contact Form 7
 global $menu;
 unset($menu[5]); // 投稿
 unset($menu[25]); // コメント
 unset($menu[75]); // ツール
 unset($menu[80]); // 設定
 }
 }
add_action('admin_menu', 'remove_menus');
```

[WordPressで記事の公開ボタンを押したら確認ダイアログを出す](http://m.designbits.jp/15122122/)

```php:ターミナル１（VPS接続用）：コマンドメモ

```

##[投稿画面の「プレビュー」ボタンを非表示にする](http://tech.belinko.net/no_preveiw_btn/)

```php:ターミナル１（VPS接続用）：コマンドメモ
//プレビューボタンと下書きとして保存ボタンの非表示（Chrome検証ツールで探したものもある）
//プレビューボタンと下書きとして保存ボタンの非表示
add_action('admin_print_styles', 'admin_preview_css_custom');
function admin_preview_css_custom() {
   echo '<style>#save-action {display: none;}</style>';
   echo '<style>#preview-action {display: none;}</style>';
   echo '<style>#misc-publishing-actions {display: none;}</style>';
   echo '<style>#formatdiv {display: none;}</style>';
   echo '<style>#categorydiv {display: none;}</style>';
   echo '<style>#tagsdiv-post_tag {display: none;}</style>';
   echo '<style>#collapse-menu {display: none;}</style>';
   echo '<style>#se-metabox {display: none;}</style>';
}
```


##AdvancedCustomFieldsでユーザープロフィールの項目を新たに追加する方法
2つめの写真の下のシカクが重要。AdvancedCustomFieldsプラグインで新規追加して、項目（電話番号とか）を作って、
<font color="red"><B>「位置」-「ルール」のところの３条件を、「ユーザー」「等しい」「全て」にセットすると、ユーザープロフィールの項目が新規追加のときと編集のときに追加される。</B></font>
く・・・っ！「user-new.php」いじっちゃったりすごく遠回りしたなぁ・・・経験値は得てるからいいけど・・・　
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/32bc02cb-073b-e946-8c1b-ce2e8eabaf67.png)

![image](https://qiita-image-store.s3.amazonaws.com/0/94562/418ae55b-5252-973c-b747-10d88f836d7a.png)




##[管理バーの項目を削除する](http://wpcj.net/260)

```php:ターミナル１（VPS接続用）：コマンドメモ
/**
 * 管理バーの項目を削除します。
 */
function remove_bar_menus( $wp_admin_bar ) {
    $wp_admin_bar->remove_menu( 'wp-logo' );      // ロゴ
    $wp_admin_bar->remove_menu( 'my-account' );   // マイアカウント
    $wp_admin_bar->remove_menu( 'comments' );     // コメント
}
add_action('admin_bar_menu', 'remove_bar_menus');
```

##[「あなたのプロフィール」管理画面の項目を非表示にする方法](https://www.cherrypieweb.com/weblog/technical/20151220020923.php)

##[ログイン時に権限ごとに違うページに遷移させる](http://mizyupon-rpg.com/posts/1174.html)

```php:ターミナル１（VPS接続用）：コマンドメモ
// 管理者かそうでないか、で十分
add_action('wp_login', 'redirect_page', 10, 2);
function redirect_page($user_login, $user)
{
	$user_role = $user->roles[0];
	if( $user_role != 'administrator' ){
	    //管理者じゃなければ「陽だまり試験場」のホームのページに行く
	    wp_redirect( home_url() );
	    exit();
	}
}
```

##プラグイン「UserRoleEditor」をインストールする
・権限は「管理者」と「寄稿者」しか使わない。「寄稿者」は「新規投稿」ができるだけ、の状態にした。

##ユーザープロフィールのデフォルト項目を非表示
<font color="red" size="+2"><B>ユーザープロフィールのデフォルト項目を非表示にするのがムズい！</B></font>:sob:
[意外に難しい？　WordPressの「あなたのプロフィール」管理画面の項目を非表示にする方法](https://www.cherrypieweb.com/weblog/technical/20151220020923.php)
このページに、
・「ユーザー」－「あなたのプロフィール」画面の設定項目については、上remove_meta_box関数やプラグインが使えません。
・ユーザー管理画面には「表示オプション」タブすらない
・ユーザー管理画面はそうではなく、フォーム部品がHTMLでほぼ直書き

などと書かれている...
僕もしばらく調べ回ってみたけどどうやらHTML直修正が早そう（このページの人は js でやってる）

###user-new.php
もうここまできたらディープカスタマイズの世界だね
このディレクトリまで行って、「user-new.php」を開いてください（雑...
テーマディレクトリより上の階層です
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/5b9d1ecd-e163-7b8b-72c1-ba290c465731.png)

```php:ターミナル１（VPS接続用）：コマンドメモ
# pwd
# ls -l
# vi ../../../wp-admin/user-new.php
# cd ../../var/www/html/wp-admin
# vi user-new.php
```
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/d445a83b-51c4-9248-1b33-5314050a9d41.png)

first_nameとか消したいような名前がついているところをコメントアウト
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/a632feb7-ddd7-adab-fbb4-5590aa575992.png)

その少し下のHTMLにも、なんだか「ラベル」と「テキストボックス」のセットになってるっぽいので、
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/04b6169b-2305-3569-7593-59c5fe2cc041.png)

Chromeでみてもそういうセットになってるので３セット（姓・名・ウェブサイト）をコメントアウトする。
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/b2c1f472-46c0-064a-140b-72e8c48a1ec9.png)

コメントアウトしました。
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/684e7db7-5728-8355-0de0-1334ba80fe78.png)

消えたぜ！:muscle::poop:
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/883b96c5-a741-f0f7-dc4e-582e5ac8ed1b.png)




###user-edit.php
この調子で既存プロフィールの変更（＝あなたのプロフィール）のほうもいくぞ

```php:ターミナル１（VPS接続用）：コマンドメモ
# pwd
# ls -l
# vi ../../../wp-admin/user-edit.php
# cd ../../var/www/html/wp-admin
# vi user-edit.php
```
chromeで、このへんは「form-table」という名前であることがわかったのでおまえらいらねー！ってことで
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/e9dd12de-111d-a091-8c1f-9a2cdcc39b1d.png)

![image](https://qiita-image-store.s3.amazonaws.com/0/94562/fc3d25ae-504f-1f71-f4fd-df92621ee98a.png)

消えたー！なんか見方がわかってきてちょっと気持ちよくなってきた。
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/0c14055e-0db7-e8b3-dbbd-ad733f2093d1.png)




同じ要領で繰り返してこうなった

##表示をログインユーザーに限定
"子テーマの" functions.phpに<font color="red"><B>追記</B></font>
###functions.php
```php:ターミナル１（VPS接続用）：コマンドメモ
/*-------------------------------------------*/
/*  表示をログインユーザーに限定する
/*-------------------------------------------*/
function require_login() {
    if ( ! is_user_logged_in() && ! preg_match( '/^(wp-login\.php|async-upload\.php)/', basename( $_SERVER['REQUEST_URI'] ) ) && ! ( defined( 'DOING_AJAX' ) && DOING_AJAX )  && ! ( defined( 'DOING_CRON' ) && DOING_CRON ) ) {
        auth_redirect();
    }
}
add_action('init', 'require_login') ;
```

##伝票一覧画面（子種一覧）に表示される件数を絞る
（「最近の投稿」はあとで削除予定かなぁ、絞り方わからないし、、、）
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/11225211-19af-07d8-5876-cba42e90f489.png)

１．ユーザーIDを取得
２．WP_Queryでログイン者だけに投稿を絞るクエリーを作成し「query」に格納
３．while〜のところの２ヶ所に「query->」と追記

###index.php
"子テーマの" index.phpに<font color="red"><B>追記</B></font>

```php:ターミナル１（VPS接続用）：コマンドメモ
<?php

// 「あなたの投稿したものだけ」表示するクエリを発行 WP_QUERY
$user = wp_get_current_user();
$userID = $user->ID;
$query = new WP_Query( 'author='.$userID );

if ( have_posts() ) : ?>
        <?php
        // Start the loop.
        while ( $query->have_posts() ):$query->the_post();
```

#「再度購入」を実装
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/f2ede2cf-22d6-31e0-3725-f3498b79804d.png)
Amazonみたいな機能は必要だよね。
同じ住所に対して同じ個数を送るとか、個数だけいじれて再注文とか。便利よね。ここでSQLの発行が必要になる。
SQLの発行が必要なタイミングは2つ。
１．再度購入をしたいときの「INSERT」
２．差分発行の「UPDATE+INSERT」

１に関しては、単純にパラメータを同じにしたINSERTの発行をすればよい。
２に関しては、例えば注文数8なのにその日のオペレーションがオーバーして7こしか送れなかったときに '注文数' を7に更新して、さらに '注文数' が1の「再度注文」をするとよい。 

##WordpressPHPで打つMySQL基本

```mysql:MySQL：memo
#db名：wordpress
#選択したいテーブル名：wp_users

#mysql起動
mysql -u root -p

#wordpressというデータベースのなかには何のテーブルがあるんだっけ？
SHOW TABLES FROM wordpress;

#データベース選択
USE wordpress;

#テーブルの構造を見る
SHOW COLUMNS FROM wp_posts;

#SQL発行
SELECT * FROM wp_users;
```

##single.php
[ITかあさん：WordPressでQueryをゴリゴリ操作 wpdbまとめ](http://www.kaasan.info/archives/3576)
[Codex関数リファレンス / wpdb Class](https://wpdocs.osdn.jp/%E9%96%A2%E6%95%B0%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9/wpdb_Class#.E5.88.97.E3.81.AE_UPDATE)
[WordPressでシステム開発をする時に必要なクエリ操作について](http://qiita.com/yousan/items/f29e7010a1384c1e1206)

###UPDATE
投稿id（post_id） '243' の注文数（ORDERCOUNT）を '8' に変える。

```php:PHP：UPDATE
<?php
global $wpdb;
$wpdb->update('wp_postmeta', array('meta_value'=>'8'), array('post_id'=>'243', 'meta_key'=>'ORDERCOUNT'), '%d', array('%d','%s'));
?>
```

wordpressのAdvancedCustomFieldで追加した項目の値はMySQLの「wp_postmeta」に入るが、このテーブルの列項目は4つである（ムズカシク言うと正規化が進んでいて独自の項目がいくらでも追加できる仕様になっている）
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/829c3758-79eb-2c27-7814-4774117c37ac.png)

何が言いたいかというと、post_idが '243' の meta_keyが 'ORDERCOUNT' というところまで指定して、その値は8という理解をする必要がある。
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/1b0a1ab4-7626-286e-7eb8-12611d827560.png)

つまり、投稿id（post_id） '243' の注文数（ORDERCOUNT）を '8' に変える（UPDATE）構文は、以下のようになる。

```php:PHP：UPDATE（整理）
<?php

#dbいじりの前にかならず必要
global $wpdb;

$wpdb->update(

  #更新対象のテーブル
  'wp_postmeta', 

  #更新する値
  array('meta_value'=>'8'), 

  #WHERE 
  array('post_id'=>'243', 'meta_key'=>'ORDERCOUNT'),　

  #更新する値のデータフォーマット（数値です）
  '%d', 

  #WHEREのデータフォーマット（最初が数値、つぎが文字での指定です）
  array('%d','%s')); 

?>
```
ようやく整理できた！
なお、第2引数（更新する値）は必ず array 形式の書き方になる。
なんとか array を少なくしようとして試行錯誤したけど「更新する値」のところは連想配列にせざるを得ないようだ。
列と値をペアにする書き方をする以上、その調子だと第3引数の WHERE も、条件が1つだとしても array 形式になるな。
だから array をハズすことができたのは、今回は第3引数のみだった。

なお、「=>」はダブルアロー演算子と言って、連想配列のときに使う。ダブルアローを知らないまま array をどうにかハズそうと試行錯誤して沼にはまっていた...。

###INSERT
さて、更新は目的の値を見つけることができればいいけど新規明細発行（INSERT）の場合は、必ず入れなければいけないいくつかの値があるはずだ。当ツールは、１つの伝票を１つの投稿と位置づけて投稿の中身はほぼカスタムフィールドだけで作成されている。
つまり、WordPressの [テーブル構造（下図）](https://wpdocs.osdn.jp/%E9%96%A2%E6%95%B0%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9/wpdb_Class#.E8.A1.8C.E3.81.AE_INSERT) を見る限りでは「wp_posts」で投稿そのものを作り、「wp_postmeta」でカスタムフィールドの値をつくれば良いことになる。
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/565e09ce-d731-9e3f-cd6d-73f996bd00a7.png)


####[wp_postsの構造](http://wpdocs.osdn.jp/%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9%E6%A7%8B%E9%80%A0#.E3.83.86.E3.83.BC.E3.83.96.E3.83.AB.EF.BC.9A_wp_posts)
んー・・・FieldとDefault（初期値）を見比べて、初期値になっちゃいけないのを抜き出すか、、、。
post_author：投稿者のユーザID
post_date：投稿日時（日本時間）
post_date_gmt：投稿日時（協定世界時）

![image](https://qiita-image-store.s3.amazonaws.com/0/94562/93f67764-aab1-a8ec-ee70-3fdcbfa9af1f.png)

気になって調べた項目
post_excerpt：excerpt＝抜粋
post_status：'publish': 公開済み
comment_status：'open': 許可 243のpostを見る限りは closed

```mysql:SQL：INSERT
INSERT INTO wp_posts (post_author, post_date, post_date_gmt, comment_status ) VALUES (1, NOW(), utc_timestamp(), 'closed');
```
すでに投稿してある「実際のデータ」と「初期値」と「SQLを発行して増えたデータ」を比べてみた。
...まぁいいんじゃねぇかなぁ。
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/55b46d69-44dd-a9b3-6ffa-dc4110847aaa.png)


####[wp_postmetaの構造](http://wpdocs.osdn.jp/%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9%E6%A7%8B%E9%80%A0#.E3.83.86.E3.83.BC.E3.83.96.E3.83.AB.EF.BC.9A_wp_postmeta)
meta_id は auto_increment のためいじらず。
post_idとmeta_keyとmeta_valueは、まぁ一般データ的に見ても必要だよね。
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/c01b4a41-2f69-d7ad-5432-3f9fc867e415.png)

```mysql:SQL：INSERT
#WordPressで必須項目にしちゃったやつや、初期値が入る設定にしちゃったやつ、入ってないと不自然なやつは全部
INSERT INTO wp_postmeta (post_id, meta_key, meta_value) VALUES (243, 'PRODUCT_NAME', 'プルーン');
INSERT INTO wp_postmeta (post_id, meta_key, meta_value) VALUES (243, 'ORDERCOUNT', '10');
INSERT INTO wp_postmeta (post_id, meta_key, meta_value) VALUES (243, 'USE', 'ギフト');
INSERT INTO wp_postmeta (post_id, meta_key, meta_value) VALUES (243, 'DESTINATION_POSTAL', '3310052');
INSERT INTO wp_postmeta (post_id, meta_key, meta_value) VALUES (243, 'DESTINATION_ADDRESS', 'BAMWEST101');
INSERT INTO wp_postmeta (post_id, meta_key, meta_value) VALUES (243, 'DESTINATION_NAME', 'yoshitaka');
INSERT INTO wp_postmeta (post_id, meta_key, meta_value) VALUES (243, 'DESTINATION_KEISYO', '様');
INSERT INTO wp_postmeta (post_id, meta_key, meta_value) VALUES (243, 'DESTINATION_TEL', '9093036833');
```

そういえばさっきからダブってるこれなによ？
これな（赤線から上が正規画面からの投稿、赤線から下がSQL直）
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/b38cb908-3cf3-3268-c1a8-f9b3e24db5b5.png)


[ここ（ACFプラグインを使う際の注意点など）](http://notnil-creative.com/blog/archives/1752) を見てみると...要は
１．先頭にアンダーバーを付けたデータがあって、これは<font color='red'>ACFのフィールドキー</font>である。
２．フィールドキーがないと、<font color='red'>ACFのget_field関数で正しくデータを読めない。</font>
３．管理画面から一度でも保存すればACFのフィールドキーは生成できるが、それ以外の方法<font color='red'>（フィールドキーを参照するAPI等）は見つかっていない。</font>
４．get_field関数が使えないと<font color='red'>集計ができない。</font>



ということらしい。
あぁ、、、<font color='red'><B>振り返るとだいぶディープダンジョンな感じになってきたな（笑</B></font>

つまりだ・・・新規投稿をSQLで行うときは
１．(SQL)最新POSTのフィールドキーを求める（必須項目のみでいいね）
２．(PHP)アンダーバーを先頭につけた meta_key でもって、フィールドキーを meta_value に突っ込む
という工程が必要になる。
必須項目ではないところは、ユーザーの更新時にまかせる。

[公式の英語の質問ページ](https://support.advancedcustomfields.com/forums/topic/get-field-key-by-field-name/) にもなくて数時間悩んだ挙句、
あれ？:thinking:
１．欲しいフィールドキー名を配列で引数に取り込んで
２．IN句でアンダースコアを先頭につけながらDISTINCTで取得
すればいいんじゃないの？という結論

```SQL:SQL：SELECT
SELECT DISTINCT meta_key, meta_value FROM wp_postmeta WHERE meta_key IN (
'_PRODUCT_NAME',
'_ORDERCOUNT',
'_USE',
'_DESTINATION_POSTAL',
'_DESTINATION_ADDRESS',
'_DESTINATION_NAME',
'_DESTINATION_KEISYO',
'_DESTINATION_TEL',
'_DESTINATION_TIMEZONE');
```

いいじゃん。どや！外人！:grin:（外人ってゆーな！）
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/cec166bb-7a0a-3758-bab8-3e2f23e3deab.png)

```PHP:PHPメモ（カンマで配列にスプリット）
<?php
$fruit = explode(',', 'りんご,みかん,いちご,メロン,バナナ');
foreach($fruit as $value){
    // SQLを生成して
    echo $value . “<br>”;
}
?>
```

##HTML基礎（ボタンを押したあとデータはどこへ行くのか？）
・[フォームデータを送信する](https://developer.mozilla.org/ja/docs/Web/Guide/HTML/Forms/Sending_and_retrieving_form_data)

例えばこういうソースを single.php に書き込むと

```HTML:HTML基礎
<form action="/" method="get">
  <input name="say" value="Hi">
  <input name="to" value="Mom">
  <button>Send my greetings</button>
</form>
```

１．'say' 変数に 'Hi' という値が入ったテキストボックス
２．'to' 変数に 'Mom' という値が入ったテキストボックス
３．'Send my greetings' と書かれた送信ボタン
が出てきた！
ボタンを押してみると...
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/36a1e296-003d-62be-4e18-1ccb0c189acf.png)

アドレスバーに変数名と値が出てきた！そういうことか！
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/88697cff-c3cb-4847-7c0c-0f11825ae4bb.png)


##登録フォームを作成（ボタンを押したらSQL発行）
・[WordPressで登録フォームを作成](http://dim5.net/wordpress/development-registration-form.html)（ここのソースを読んで最適化した）

###single.php
```PHP:single.php
<?php
/**
 * The template for displaying all single posts and attachments
 *
 * @package WordPress
 * @subpackage Twenty_Fifteen
 * @since Twenty Fifteen 1.0
 */

get_header(); ?>


        <div id="primary" class="content-area">
                <main id="main" class="site-main" role="main">

                <?php
                // Start the loop.
                while ( have_posts() ) : the_post();
                        get_template_part( 'content', get_post_format() );
                // End the loop.
                endwhile;
                ?>

                <?php
                // POSTリクエストの場合(下の方で再度購入ボタンが押されて再起した(page_stateに1が入った)ときに通る）
                if( isset($_POST['page_state']) && $_POST['page_state'] == '1' )
                {
                        $orderCount = $_POST['ReOrderCount'];

                        // 投稿を作成
                        SQLInsert_posts();

                        // 新規投稿のIDを取得
                        $postid = GetLatestPostId();

                        // 商品名
                        $col = 'PRODUCT_NAME';
                        SQLInsert_postmeta($postid, $col, get_field($col));

                        // 注文数
                        $col = 'ORDERCOUNT';
                        SQLInsert_postmeta($postid, $col, $orderCount);

                        // 用途
                        $col = 'USE';
                        SQLInsert_postmeta($postid, $col, get_field($col));

                        // お届け先郵便番号
                        $col = 'DESTINATION_POSTAL';
                        SQLInsert_postmeta($postid, $col, get_field($col));

                        // お届先住所
                        $col = 'DESTINATION_ADDRESS';
                        SQLInsert_postmeta($postid, $col, get_field($col));

                        // お届け先名
                        $col = 'DESTINATION_NAME';
                        SQLInsert_postmeta($postid, $col, get_field($col));

                        // お届け先敬称
                        $col = 'DESTINATION_KEISYO';
                        SQLInsert_postmeta($postid, $col, get_field($col));

                        // お届け先電話番号
                        $col = 'DESTINATION_TEL';
                        SQLInsert_postmeta($postid, $col, get_field($col));

                        // お届け時間帯
                        $col = 'DESTINATION_TIME';
                        SQLInsert_postmeta($postid, $col, get_field($col));

                        // ステータス
                        $col = 'STATUS';
                        SQLInsert_postmeta($postid, $col, '未着手');

                        $message = '再注文しました。';
                        ?>
                        <div class="hentry entry-header"><p><strong><?php echo $message ?></strong></p></div>

                        <!-- 記事一覧へ戻るボタン -->
                        <form class="hentry entry-header" method="post" action="/">
                                <button>ホームへもどる</button>
                        </form>

                <?php
                }else{
                ?>

                        <?php
                        // %7Eはチルダ。チルダ'~'をナミ線'〜'に置換せよ
                        $crrURL = str_replace('%7E', '~', $_SERVER['REQUEST_URI']);
                        ?>
                        <!-- 再度購入ボタン -->
                        <form class="hentry entry-header" method="post" action="<?php echo $crrURL ?>">
                                <P>同じ商品を同じお届け先に再注文できます。再注文数を入力してください。</P>
                                <input type="hidden" name="page_state" value="1">
                                <input type="number" name="ReOrderCount" style="width:100px; text-align:right;" value="1">
                                <button>再度購入</button>
                        </form>

                <?php
                }
                ?>

                </main>
        </div><!-- .content-area -->

```

###★WordPressPHP TIPS
「真/偽」チェックボックスは、get_field()すると「1」か「無」が返る。ややこしい！
ヘルパーファンクション（falseかtrueを返すだけの関数）作る手もあるんだけど、、根雪みたいなもんだからこっちに慣れるか、、、）
[Advanced Custom Fieldsによるカスタムフィールドの出力 [チェックボックス・ラジオボタン編]](http://www.kerenor.jp/advanced-custom-fields-checkbox/)

```PHP:WordPressPHP-TIPS
if( get_field('field_name') ) //真の場合
{
    echo '真の場合の処理';
}
else // 偽の場合
{
    echo '偽の場合の処理';
}
```

###★ネット回線がぶちぶち切れながら作業してたときにハマったCSSエラー
僕ね、WiMAXのモバイルで接続しながらやってるんだけど、これ結構接続おちるのね...。
なぜか突然CSSが死んだ時期があって functions.php の名前を変えてカラの functions.php を作ったりしながらようやく復旧した。
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/ebf31aa6-badc-37d8-df99-f570ae8d0327.png)
（この画面もう見たくない...）

なぜかこの行が消えていた。。。恐ろしい。。。functions.php もだんだん積み上がってきたところでこういうの起こるとまじでわからん。固定回線でやりてーぇ・・・
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/07f0f84a-3954-0d47-9cb1-e7fe8764dc8a.png)

```PHP:functions.php
<?php

// 親テーマのCSSも読んで下さいね、という命令
function theme_enqueue_styles() {
    wp_enqueue_style( 'parent-style', get_template_directory_uri() . '/style.css' );
}
add_action( 'wp_enqueue_scripts', 'theme_enqueue_styles' );
```
処置の結論から言うと
・CSSデザインが崩れたならやっぱりCSSのところに原因がある。
・子テーマに必要なファイルは style.css と functions.php。最低限の構成でトライ。
・動いていた時期のソースはおさえとけ（GitHub覚えねぇとなぁ、、、）
よけいなとこで時間食ったなぁ、、、。みなさんも回線に注意ね。っていうかこのクソ重SSHも原因なんじゃないか？

##カテゴリーをつけたい
###・wp_term_taxonomy
カテゴリーのテーブルのようだ
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/b382f917-e379-8dc7-9da3-c29e4226bc3c.png)

###・wp_term_relationships
記事とカテゴリーを紐付けているようだ
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/acf82492-13a2-8899-bc55-113d5d545fdf.png)

##MySQLに金額のテーブルをつくる
商品名と金額の情報を持つテーブル

```MySQL:CREATETABLE
CREATE TABLE IF NOT EXISTS M_PRODUCT (
  ID    INT UNSIGNED AUTO_INCREMENT NOT NULL,
  name  VARCHAR(100) NOT NULL DEFAULT '',
  price INT UNSIGNED NOT NULL DEFAULT '0',
  PRIMARY KEY (ID)
);
```
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/19aa4735-293d-07c4-91a1-7f72e1224af5.png)

![image](https://qiita-image-store.s3.amazonaws.com/0/94562/1c8dc669-9836-f5f9-fa49-83e35cf3931a.png)

```MySQL:INSERT
INSERT INTO M_PRODUCT (name, price) VALUE ('プルーン','2000');
INSERT INTO M_PRODUCT (name, price) VALUE ('生ワイン','3000');
```

```MySQL:SELECT
SELECT * FROM M_PRODUCT;
```
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/d1edae00-67c2-b886-0bc3-1ec2368166d9.png)

##改造固定ページについて
ちょっとまだメカニズムの整理追いついてないけど「できたので」まとめる（笑


###１．固定ページ新規作成
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/1ea0011a-1db5-3461-b582-deefcac3f8e2.png)

新規固定ページを作ってタイトルつけて、中身の編集なしで公開しちゃう。
今回は <font color='red'>page_id=81</font> が付与された。
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/c82d06be-9fc5-8662-59e0-ee3e0aa8fb9f.png)

ページを公開する際に、スラッグを命名する（公開したあとでもいいけど）。
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/42a7eef6-e2a2-f375-9de2-bdc1f6db8a77.png)

###２．テンプレートのコピー
親テーマで「page.php」と書いてあるものが固定ページのテンプレなので
子テーマフォルダにコピーしてきて「page<font color='red'>-csv</font>.php」という名前に変える。
これがリンケージになる。

```php:ターミナル１（VPS接続用）：コマンドメモ
[twentyfifteen-child] cp ../twentyfifteen/page.php page-csv.php
```

![image](https://qiita-image-store.s3.amazonaws.com/0/94562/45a73476-34a2-f3da-cea7-4786505beba9.png)
あとは 「page<font color='red'>-csv</font>.php」 のHTMLにPHPループ仕込んで帳票ページにするのもいいし、固定ページを独自体裁にすることができる。

###３．ページへのリンクを貼る
そうしたら子テーマ（このページを見てる人はindex.phpは子テーマにあるはず）の 「index.php」 にこんなふうにボタンでのリンクでもくっつけて、 

![image](https://qiita-image-store.s3.amazonaws.com/0/94562/2d1a0b25-4392-1077-2fc7-8c3012c198fe.png)

```php:ターミナル１（VPS接続用）：コマンドメモ
<input class="hentry" type="submit" value="請求書" onClick="location.href='/?page_id=2'">
<input class="hentry" type="submit" value="CSV出力" onClick="location.href='/?page_id=81'">
```

できあがったボタンを押すと
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/08352a54-150e-630a-a133-3afe9165127f.png)

ホラ変わった！
![image](https://qiita-image-store.s3.amazonaws.com/0/94562/516f939e-5d6d-3dd9-0800-73def92d42de.png)

###４．クエリで未着手を取り出す
[WordPress覚書 その１ 「カスタム投稿の取得とか出力とか」](http://www.mamimumeme.com/web/wordpress-wp-query)

```php:LOOP
<?php
// 「未請求」だけを表示してCSV出力
$query = new WP_Query();
$param = array(
    'post_type' => 'post',
    'category_name' => 'shop',
    'meta_query' => array(
        array(
            'key' => 'STATUS',
            'value' => '未着手'
        )
    )
);
$query->query($param);
?>

<table class="invoice">
<thead><tr>
    <th>商品名</th>
</thead>
<tbody>
<?php
if( $query->have_posts() ) :
while ( $query->have_posts() ) : $query->the_post();
?>
    <tr>
    <td><?php the_field('PRODUCT_NAME'); ?></td>
    </tr>
<?php 
endwhile; 
endif; 
?>
<?php wp_reset_postdata(); ?>
</tbody>
</table>
```