# WordPress講義4回目
## 環境構築
先週作成したテーマを利用します。
先週の資料は[こちら](https://hackmd.io/@gY8gdngQSbmAZ9WDXUEF6g/B12bMWoT3)
**先週時の授業を受けれていない方は[ここから](https://drive.google.com/drive/folders/1KPGe4vudpCcdemfPS1Dr07jlz1EujCfX?usp=sharing)先週作成したWPテーマをダウンロードして続きから作業をしてください。
Local Sites\sample\app\public\wp-content\themes
の階層にダウンロードしたmyblogというフォルダを配置してVsCodeで開いてください。**
## オリジナルのプラグインを作ってみよう
### 最小構成のプラグインを作成
#### 1. /wp-content/pluginsフォルダにcustom-post-listフォルダを作成
#### 2. custom-post-listフォルダのなかにcustom-post-list.phpを作成して以下をコピペ
```
<?php
//ヘッダー:プラグインであることの宣言。以下を記述することでプラグインとして認識される。
/**
* @package WordPress
* @subpackage custom-post-list
* @author 自分の名前
*
*
* Plugin Name: 店舗管理用プラグイン
* Plugin URI: 自分のサイト
* Text Domain: custom-post-list
* Description: 店舗管理用オリジナルカスタムフィールド Wp5.5対応版
* Author: 自分の名前
* Author URI: 自分のサイト
* Version: 1.0
* License: GPLv3+
*/
```
*これだけでプライグインとしての最小構成は完成しています。
### 店舗データ管理用のカスタム投稿システムをプラグインとして作る
#### 1. まずは以下の内容をコピペ
```
function list_init()
{
$labels = array(
'name' => _x('店舗データ', 'post type general name'),
'all_items' => __('店舗一覧'),
'singular_name' => __('データ'),
'add_new' => __('データ追加'),
'parent_item_colon' => ''
);
$args = array(
'labels' => $labels,
'public' => true,//管理画面・サイトへの表示の有無
'publicly_queryable' => true,
'show_ui' => true, //管理画面のメニューへの表示の有無
'menu_position' => 5,//管理メニューでの表示位置
'query_var' => true,
'rewrite' => true,//パーマリンク設定
'capability_type' => 'post',//権限タイプ
'map_meta_cap' => true,//デフォのメタ情報処理を利用の有無
'hierarchical' => false,//階層(親)の有無
'menu_icon' => 'dashicons-building',//アイコン画像
'supports' => array('title','thumbnail'),
// 'taxonomies' => array( '', '' ), //postと共通にする場合
'has_archive' => true, //アーカイブの有無
// 'show_in_rest' => true //Gutenbergを有効化
);
register_post_type('list', $args);
}
```
#### 2. list_init関数のなかにさらにタクソノミーの記述も追加
```
//カテゴリータイプ ポストと別のカテゴリーにする
$args = array(
'label' => 'カテゴリー',
'public' => true,
'has_archive' => true,
'show_in_rest' => true,
'hierarchical' => true,// カテゴリーを階層化する方法
);
register_taxonomy('list_cat', 'list', $args);
//タグタイプ
$args = array(
'label' => 'タグ',
'public' => true,
'has_archive' => true,
'show_in_rest' => true,
);
register_taxonomy('list_tag', 'list', $args);
```
#### 3. 最後に関数をadd_actionで登録
```
function list_init(){
省略
}
add_action('init', 'list_init');//ここを追加
```
### 管理画面の編集画面にボックスを追加
```
// 投稿と固定ページの編集画面メインカラムにボックスを追加
function add_list_field()
{
// $screens = array( 'post', 'page' );
$screens = array('list');
foreach ($screens as $screen) {
add_meta_box('list_data', '店舗データ', 'insert_list_field', $screen);
}
}
add_action('add_meta_boxes', 'add_list_field');
```
### 管理画面にフォームボックスを表示する処理
```
function insert_list_field($post)
{
// nonceフィールドを追加して後でチェックする
wp_nonce_field('save_custom_field_list', 'input_nonce_name');
// 管理画面デザイン Bootstrap
echo '<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">';
echo '<h3 class="small">店舗・会社 概要</h3>
<table class="table table-bordered adminListTable">
<tbody>
<tr>
<th>会社名・店舗名</th>
<td><input class="form-control" type="text" name="cf_company" placeholder="" value="' . esc_attr(get_post_meta($post->ID, 'cf_company', true)) . '" /></td>
<th>郵便番号</th>
<td><input class="form-control" type="text" name="cf_zip" placeholder="" value="' . esc_attr(get_post_meta($post->ID, 'cf_zip', true)) . '" /></td>
</tr>
<tr>
<th>住所</th>
<td><input class="form-control" type="text" name="cf_add" placeholder="" value="' . esc_attr(get_post_meta($post->ID, 'cf_add', true)) . '" /></td>
<th>電話番号</th>
<td><input class="form-control" type="text" name="cf_tel" placeholder="" value="' . esc_attr(get_post_meta($post->ID, 'cf_tel', true)) . '" /></td>
</tr>
<tr>
<th>営業時間</th>
<td><input class="form-control" type="text" name="cf_job_time" placeholder="" value="' . esc_attr(get_post_meta($post->ID, 'cf_job_time', true)) . '" /></td>
<th>定休日</th>
<td><input class="form-control" type="text" name="cf_holy_day" placeholder="" value="' . esc_attr(get_post_meta($post->ID, 'cf_holy_day', true)) . '" /></td>
</tr>
<tr>
<th>メールアドレス</th>
<td><input class="form-control" type="text" name="cf_mail" placeholder="" value="' . esc_attr(get_post_meta($post->ID, 'cf_mail', true)) . '" /></td>
<th>ホームページ</th>
<td><input class="form-control" type="text" name="cf_url" placeholder="" value="' . esc_attr(get_post_meta($post->ID, 'cf_url', true)) . '" /></td>
</tr>
</tbody>
</table>
';
}
```
### フォームから届いたデータを保存する処理
```
//データ保存処理
function save_custom_field_list($post_id)
{
// nonceがセットされているかどうか確認
if (!isset($_POST['input_nonce_name'])) {
return $post_id;
}
// nonceが正しいかどうか検証
if (!wp_verify_nonce($_POST['input_nonce_name'], 'save_custom_field_list')) {
return $post_id;
}
// 自動保存の場合はなにもしない
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return $post_id;
}
// ユーザー権限の確認
if (isset($_POST['post_type']) && 'page' == $_POST['post_type']) {
if (!current_user_can('edit_page', $post_id)) {
return $post_id;
}
} else {
if (!current_user_can('edit_post', $post_id)) {
return $post_id;
}
}
// データがセットされているか確認する
$param_list = array(
'cf_company',
'cf_zip',
'cf_add',
'cf_tel',
'cf_job_time',
'cf_holy_day',
'cf_mail',
'cf_url'
);
foreach ($param_list as $param) {
// ユーザーの入力を無害化する
// この無効か入れないと クロスサイトスクリプティング(XSS) 攻撃を受ける
// テスト用「"><script>alert(document.cookie);</script>」
$_POST[$param] = sanitize_text_field($_POST[$param]);
if (!empty($_POST[$param])) {
update_post_meta($post_id, $param, $_POST[$param]); //値を保存
} else { //題名未入力の場合
delete_post_meta($post_id, $param); //値を削除
}
}
}
```
### 最後に登録関数をadd_actionで登録
```
add_action('save_post', 'save_custom_field_list');
```
### あとは表示画面作成(省略したいのでコピペベース)
archive-list.php
```
<?php get_header(); ?>
<!-- Section-->
<section class="py-5">
<div class="container px-4 px-lg-5 mt-5">
<div class="row gx-4 gx-lg-5 row-cols-2 row-cols-md-3 row-cols-xl-4 justify-content-center">
<?php if( have_posts()):?>
<?php while( have_posts() ): the_post()?>
<?php
$id = get_post_thumbnail_id();
$img = wp_get_attachment_image_src($id,'large');
?>
<div class="col mb-5">
<div class="card h-100">
<!-- Product image-->
<img class="card-img-top" src="<?php echo $img[0]; ?>" alt="..." />
<!-- Product details-->
<div class="card-body p-4">
<div class="text-center">
<!-- Product name-->
<h5 class="fw-bolder"><?php the_title(); ?></h5>
<!-- Product price-->
<!-- <?php echo number_format($price);?>円 -->
</div>
</div>
<!-- Product actions-->
<div class="card-footer p-4 pt-0 border-top-0 bg-transparent">
<div class="text-center"><a class="btn btn-outline-dark mt-auto" href="<?php the_permalink(); ?>">View options</a></div>
</div>
</div>
</div>
<?php endwhile; ?>
<?php else:?>
投稿がみつかりませんでした。
<?php endif;?>
</div>
</div>
</section>
<?php get_footer(); ?>
```
single-list.php
```
<?php get_header(); ?>
<?php if( have_posts() ): ?>
<?php while( have_posts() ): the_post()?>
<?php
$id = get_post_thumbnail_id();
$img = wp_get_attachment_image_src($id,'large');
$cf_company = get_post_meta(get_the_ID(),'cf_company',true);
$cf_zip = get_post_meta(get_the_ID(),'cf_zip',true);
$cf_add = get_post_meta(get_the_ID(),'cf_add',true);
$cf_tel = get_post_meta(get_the_ID(),'cf_tel',true);
$cf_job_time = get_post_meta(get_the_ID(),'cf_job_time',true);
$cf_holy_day = get_post_meta(get_the_ID(),'cf_holy_day',true);
$cf_mail = get_post_meta(get_the_ID(),'cf_mail',true);
$cf_url = get_post_meta(get_the_ID(),'cf_url',true);
?>
<!-- Product section-->
<section class="py-5">
<div class="container px-4 px-lg-5 my-5">
<div class="row gx-4 gx-lg-5 align-items-center">
<div class="col-md-6"><img class="card-img-top mb-5 mb-md-0" src="<?php echo $img[0]; ?>" alt="..." /></div>
<div class="col-md-6">
<div class="small mb-1"></div>
<h1 class="display-5 fw-bolder"><?php the_title(); ?></h1>
<div class="fs-5 mb-5">
<span><?php echo $cf_company;?></span>
</div>
<div class="fs-5 mb-5">
<p><?php echo $cf_zip;?></p>
<p><?php echo $cf_add;?></p>
<p><?php echo $cf_tel;?></p>
<p><?php echo $cf_job_time;?></p>
<p><?php echo $cf_holy_day;?></p>
<p><?php echo $cf_mail;?></p>
<p><?php echo $cf_url;?></p>
</div>
</div>
</div>
</div>
</section>
<?php endwhile;?>
<?php else:?>
記事が見つかりませんでした。
<?php endif?>
<?php get_footer(); ?>
```