---
# System prepended metadata

title: WordPress講義4回目

---

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

