事例紹介(復旧・実戦系)

【プラグイン】無料在席キャスト管理システム krc-cast-manager を使ってみた

無料在席キャスト管理システム krc-cast-manager を使ってみた
WEBさん
WEBさん

夜のお店系の WordPress サイトで定番なのが「キャスト在席をリアルタイムで出したい」というニーズ。今回は krc-cast-manager というプラグインに出会って、運用してみた所感と不具合修復のメモです。

※ 本記事は2023年当時の事例です。 現在の WordPress 6.x / PHP 8.x 環境では推奨手順が変わっている可能性があります。最新の対応方針は 復旧サービス または ご相談窓口 から確認ください。

2023-05-07

ショートコード[todayscasthtml]の不具合を解消するPHP コードを追記しました。

先日、夜のお店のWordPress サイトをメンテナンスする機会がありました。

そのサイトには「krc-cast-manager」という無料在席キャスト管理プラグインがインストールされており、不具合を修復する案件でした。

ココナラでも、このプラグインに関するご相談を 2 回ほどいただいたことがあります。

実はこのプラグイン、無料とは思えないほど優秀で、夜のお店の界隈では有名なプラグインのようです。

WEB 先案内の性格上、ちょっとクセがあるけど便利でマニアックなプラグインには目がありません。そこで、頑張って検証環境で構築してみました。

ところが、このプラグインはインストールするだけでは動きません (考えが浅はかでした…)。

前提知識として、テンプレートの理解とPHP コーディングスキルが必要です。

さらっといってしまいましたが、これだけでもハードルが高いです。

なので、まずは、テンプレートを理解するため、テーマテンプレートとモジュールテンプレートを簡単に説明します。

次に、プラグインとテーマを連携するため、テンプレート作成とショートコード関数を作ります。

最後に実際に構築したデモサイトの画面コピーをご覧いただきます。

それでは、はじめます! ٩( ‘ω’ )و

※WordPress初学者には難易度の高い内容となっております(>人<;)

テンプレート構造

テーマテンプレート

WordPress が URL の要求に従って読み込むファイルを「テーマテンプレート」と呼びます。

テーマには、テーマテンプレートだけでなく、スタイルシート・画像・各種ファイルも含められます。

ただし、以下のファイルが WordPress にとって特別な意味を持つことは覚えておいてください。

追加情報はテンプレート階層をご覧ください。
Noファイル名説明
1style.cssメインのスタイルシート
テーマにはこのファイルが必須で、テーマのヘッダ情報を含まなければなりません。
2rtl.cssRTL スタイルシート
ウェブサイトのテキスト方向が右から左の場合、このファイルが自動的に適用されます。
RTL スタイルシートは the RTLer プラグインを使って生成することもできます。
3index.phpメインテンプレート
(親テーマのテンプレートを利用するのではなく) このテーマ自身のテンプレートを設けるなら index.php は必須。
4comments.phpコメントテンプレート
5front-page.phpフロントページテンプレート
home.phpとfront.phpが両方存在した場合は、front-page.phpがフロントページ表示用のテンプレートとして使われます。
6home.phpホームページテンプレート
フロントページの表示(にデフォルトとして設定されている最新の投稿)に使われる。
固定ページをフロントページとして設定した場合、指定した固定ページがフロントページの表示に使われます。
7single.php個別投稿テンプレート
ひとつの投稿が要求 (クエリ) されたときに使用。
このクエリテンプレートが存在しないときは index.php が使われる。
この他のクエリテンプレートも同様。
8single-<post-type>.phpカスタム投稿タイプの個別投稿が要求 (クエリ) されたときに使われるテンプレート
例えば books というカスタム投稿タイプを個別表示するためには single-books.php が使われる。
9page.php固定ページテンプレート
特定の固定ページが要求されたときに使用。
10category.phpカテゴリテンプレート
あるカテゴリが要求されたときに使用。
11tag.phpタグテンプレート
タグが要求されたときに使用。
12taxonomy.phpタクソノミーテンプレート
カスタム分類内の個別項目が要求されたときに使用。
13author.php作成者テンプレート
作成者が要求されたときに使用。
14date.php日付別テンプレート
ある日付または時刻が要求されたときに使用。年、月、日、時、分、秒。
15archive.phpアーカイブテンプレート
あるカテゴリ、作成者、日付が要求されたときに使用。
各クエリの種類に対応する category.php、author.php、date.php がそれぞれ存在する場合は、
そのクエリに対してアーカイブテンプレートは無効となる。
16search.php検索結果テンプレート
ある検索が実行されたときに使用。
17attachment.php添付ファイルテンプレート
特定の添付ファイルを個別表示するときに使用。
18image.php添付画像ファイルテンプレート
特定の添付画像ファイルを個別表示するときに使用。存在しない場合は attachment.php が使用される。
19404.php404 Not Found テンプレート
WordPress が要求に合う投稿やページを見つけられなかったときに使用。_
20function.phpテーマ関数ファイル
このファイルは基本的にプラグインのような動作をし、現在使っているテーマ内に存在していれば、
管理画面とサイト表示の両方で、自動的に WordPress の初期化中に読み込まれます 。
これらのファイルは、テンプレート階層に従って適用できるファイルがあるとき、または対応する条件タグが true を返すとき、index.php に代わって使われます。そのため、WordPress にとって特別な意味を持ちます。

たとえば、個別投稿が表示される際は is_single() 関数が ‘true’ を返します。有効化中のテーマ内に single.php があれば、ページ生成にはこのテンプレートが使われます。

テーマの関数ファイル function.php

テーマでは、サブディレクトリ内に functions.php というファイル名で「関数ファイル」をオプション配置できます。

このファイルは基本的にプラグインのように動作します。現在使用中のテーマ内に存在すれば、管理画面・サイト表示の両方で、WordPress の初期化中に自動的に読み込まれます。

関数を functions.php に定義するのか、プラグインに定義するのか、に関して

同じ関数を「1 つ以上のテーマで使用可能にする必要」がある場合、その関数は functions.php ではなくプラグイン内で定義する方が良いです。

たとえば、

デフォルトでは、投稿一覧ページや固定ページ一覧にスラッグや Post ID は表示されません。

プラグインやテーマの設定時、これは意外に不便です。

一覧画面で確認できるようにしておくと、ストレスフリーで作業できます。

スラッグや Post ID を表示する関数は、テーマを跨いで使えると、テーマ切り替え後も表示が維持されて困りません。

このような状況では、プラグイン内で定義しておく方が良いです。

モジュールテンプレート

前述のテーマテンプレートから呼び出されるのが「モジュールテンプレート」です。

別名、パーツテンプレートとも呼ばれています。

名前のとおり、ページ内の一部を表示させるテンプレートファイルです。

WordPress のテンプレートファイルは、サイトの構成によってどのファイルを使うかを考え、テンプレートを選ぶ必要があります。

これらのテンプレート内には、共通で使う部分があります。

たとえばヘッダーやフッターは、全サイト共通部分として使うことが多いです。

そこで、1 ページの中でも複数ページで共有するパーツを分けて管理するため、『モジュールテンプレート (パーツテンプレートファイル)』が用意されています。

これらをうまく使えば、1 箇所の修正でページ全体を変更できます。サイト運用を効率化できます。

ただし、サイト設計時にどのように分けるかを考えないで構築すると収集がつかなくなりますので、作成時にしっかりとルールを決めることをおすすめします。

モジュールテンプレートは、これからテーマを自作しようと思っている方が知っておくと役に立ちます。

ここでは、モジュールテンプレートの種類と役割について見ていきます。
Noファイル名説明
1header.phpヘッダーテンプレート
ヘッダー部分で読み込まれる。
2footer.phpフッターテンプレート
フッター部分で読み込まれる。
3sidebar.phpサイドバーテンプレート
サイドバー部分で読み込まれる。
4searchform.php検索フォームテンプレート
検索フォームの表示。
5comments.phpコメントテンプレート
comments_template()で読み込まれる。
6content-page.php固定ページ内コンテンツテンプレート
固定ページ内コンテンツの表示。page.phpにおいてget_template_part('content','page')で読み込まれる。
このファイルが存在しない場合、content.phpが読み込まれる。
7content-single.php個別投稿ページ内コンテンツテンプレート
個別投稿ページでのコンテンツの表示。 single.phpにおいてget_template_part('content','single')で読み込まれる。
このファイルが存在しない場合、content.phpが読み込まれる。
8content.phpコンテンツテンプレート
一覧ページや検索結果ページなどでのループ内で表示。
get_template_part('content') で読み込まれる。

header.php

HTML ファイルの宣言文からヘッダーエリアに使うファイルとして、『header.php』があります。

どこの領域までをヘッダーにするかは制作者の判断になりますが、例えばgoogleのようにロゴをイベント毎に変えたかったり、ヘッダーの装飾を変えたかったりする際には、HTML宣言文からid=”header”要素までを「header.php」内にすることによって、このファイルを修正することによってどのカテゴリー、固定ページを一括で変更できます。

「header.php」を呼び出すWordPress のテンプレートタグは『<?php get_header(); ?>』となります。
ページ下部のフッターエリアから HTML 閉じタグまでを担当するファイルとして、『footer.php』があります。

コピーライトのみのような場合やフッターにも情報を多く入れる場合など、ページのフッター情報を一元管理する際には、id=”footer”要素とHTMLの終了タグを「footer.php」内にすることによって、このファイルを修正することによってどのカテゴリー、固定ページを一括で変更できます。

「footer.php」を呼び出すWordPress のテンプレートタグは『<?php get_footer(); ?>』となります。
ブログや通常サイトなど 2 カラム構成の場合、サイド領域に使うファイルとして『sidebar.php』があります。

メインコンテンツのサイドにある領域を一元管理にする際には、id=”sidebar”要素などを「sidebar.php」内に設定します。こうすることによってどのカテゴリー、固定ページを一括で変更できます。

「sidebar.php」を呼び出すWordPress のテンプレートタグは『<?php get_sidebar(); ?>』となります。

また header / footer / sidebar などの命名はありますが、header だからヘッダーエリアしか使えない、ということはありません。分かりやすさのための命名と捉えてください。

テンプレートファイルだけでページを分けてしまうと共通部分の修正作業を個別に行わなければいけなるのでサイト全体を考える際に各要素のモジュール化を意識するとよいでしょう。

searchform.php

ページ内にサイト内検索フォームなどを入れるモジュールテンプレートとして「searchform.php」があります。

よく見かけるのは、サイトのヘッダーエリアに配置されているものです。

検索結果で見つからない場合、「ページが見つかりませんでした」メッセージの下に呼び出します。ユーザーは画面上部に戻らずに、すぐ別のキーワードで再検索できるため便利です。

「searchform.php」を呼び出すWordPress のテンプレートタグは『<?php get_search_form(); ?>』となります。

comments.php

通常サイトではあまりないかもしれませんが、コメントエリアのコードをまとめるものとして「comments.php」があります。「comments.php」を呼び出すWordPress のテンプレートタグは『<?php get_comments_template(); ?>』となります。

ここまでの 5 つが、名前が決まっているモジュールテンプレートファイルです。

検証環境

  • サーバー: Local version 6.0.0
  • PHPバージョン: 7.4.1
  • WordPressバージョン: 5.7.2
  • テーマ: Zakra Child
  • プラグイン: krc-cast-manager

プラグイン全体像

krc-cat-manager

kurubusi.netさんが無料で公開しているWordPress のプラグインです。

風俗サイト用:無料在席キャスト管理WordPress プラグイン

風俗サイト用に作られたものですが、スタッフ管理などにも使え、いろいろ重宝しそうです。

繰り返しますが、プラグインをインストールしただけでは動きません。ある程度、自分でコードを書いたり設定したりする必要があります。

具体的には、テーマテンプレート一覧とモジュールテンプレート一覧で、赤色で強調したテンプレートを主に作成していきます。

後ほど説明するPHP コードを読んで分からなくなったら、戻って読み直してください。(WEB先案内は何回も読んでやっと理解しました(^◇^;))

使い方

kurubusi.net さんは別ページで、このプラグインの表示方法を公開しています。

他にもこのkrc-cast-managerを使い、そのデモサイトやソースコードを書いてくれているサイトがいくつかあったので、そちらも参考になるです。

ただし、重要な部分が割愛されているため、上級者向けの説明という印象です (^◇^;)

まずは上記の kurubusi.net さんのサイトから zip ファイル をダウンロードします。

ファイルの名前を「krc-cast-manager-master」から「krc-cast-manager」へ変更し、WordPress のプラグインに追加します。
プラグイン追加場所
プラグイン追加場所

追加するファイル

準備するファイルは下記の 7 つです。
※()内はテンプレートの分類です
  • archive-cast.php(テーマテンプレート)
  • content-cast.php(モジュールテンプレート)
  • content-castlist.php(モジュールテンプレート)
  • content-castschedule.php(モジュールテンプレート)
  • content-todaycastlist.php(モジュールテンプレート)
  • single-cast.php(テーマテンプレート)
  • functions.phpに追記(テーマテンプレート)

archive-cast.php

<?php
/**
 * The template for displaying archive pages
 *
 * @link    https://developer.wordpress.org/themes/basics/template-hierarchy/
 *
 * @package zakra
 * 
 * Template Name: キャスト一覧
 */
get_header(); ?>

<div id="primary" class="content-area">
    <?php echo apply_filters( 'zakra_after_primary_start_filter', false ); // WPCS: XSS OK. ?>
    <?php if ( have_posts() ) : ?>

    <header class="page-header">
        <?php
        zakra_entry_title();
        the_archive_description( '<div class="archive-description">', '</div>' );
        ?>
    </header><!-- .page-header -->

    <?php do_action( 'zakra_before_posts_the_loop' ); ?>
    <div class="row">
        <?php
        /* Start the Loop */
        while ( have_posts() ) :
        the_post();
        get_template_part('content',('castlist')); // content-castlist.phpを呼び出す

        endwhile;
        ?>
    </div>
    <?php
    do_action( 'zakra_after_posts_the_loop' );

    else :

    get_template_part( 'template-parts/content', 'none' );

    endif;
    ?>

    <?php echo apply_filters( 'zakra_after_primary_end_filter', false ); // // WPCS: XSS OK. ?>
</div><!-- #primary -->

<?php
get_sidebar();
get_footer();
PHP

content-cast.php

/*
* プラグインで設定した
*「カスタムフィールド」「画像」「タイプ管理」「グレード管理」「新人区分」
* を各変数に格納します
*/
<?php
$cast_fields = get_post_custom(); //カスタムフィールドを全部取得
$cast_screens = json_decode($cast_fields['_krc_cast_screens'][0]); //画像配列を用意
$cast_type_terms = get_the_terms($post->ID, 'krc_type'); //タイプタクソノミーを取得
$cast_grade_terms = get_the_terms($post->ID, 'krc_grade'); //グレードタクソノミーを取得
$cast_new_terms = get_the_terms($post->ID, 'krc_new'); //新人区分タクソノミーを取得
?>

/*
* ブラウザがレンダリングできるようにHTMLに組み込みます
*/
<div class="cast">
    <!-- スライドショー -->
    <div class="cast-photo">
        <?php if(empty($cast_screens)): ?>
        <img src="<?php echo get_stylesheet_directory_uri(); ?>/images/no.jpg" alt="<?php the_title(); ?>">
        <?php else: ?>
        <div class="slider">
            <ul class="top-slider">
                <?php foreach($cast_screens as $index => $value): ?>
                <li>
                    <a href="<?php echo $value; ?>" rel="gallery">
                        <img src="<?php echo $value; ?>" alt="<?php the_title(); ?> 写真 <?php echo ($index+1); ?>">
                    </a>
                </li>
                <?php endforeach; ?>
            </ul>

            <ul class="thumbnail">
                <?php foreach($cast_screens as $value): ?>
                <li alt="<?php the_title(); ?>">
                    <img src="<?php echo $value; ?>" alt="<?php the_title(); ?>">
                </li>
                <?php endforeach; ?>
            </ul>
        </div>

        <?php if( empty($cast_new_terms) ): ?>
        <?php else: ?>
        <span class="new_cast badge">New</span>
        <?php endif;?>
        <?php endif; ?>
    </div>
    <div class="cast-profile">
        <div class="cast-meta">
            <figure class="wp-block-table is-style-stripes">
                <table>
                    <tbody>
                        <tr>
                            <td>名前</td>
                            <td>
                                <?php echo esc_html($cast_fields['_krc_name'][0]);?>
                            </td>
                        </tr>

                        <tr>
                            <td>年齢</<?php echo esc_html($cast_fields['_krc_name'][0]);?>td>
                            <td>
                                <?php if(empty($cast_fields['_krc_age'][0])): ?>- <?php else: ?>
                                <?php echo esc_html($cast_fields['_krc_age'][0]);?>
                                <?php endif; ?></td>
                        </tr>

                        <tr>
                            <td>身長</td>
                            <td>
                                <?php if(empty($cast_fields['_krc_tall'][0])): ?>- <?php else: ?>
                                <?php echo esc_html($cast_fields['_krc_tall'][0]);?>
                                <?php endif; ?>
                                cm</td>
                        </tr>
                        <tr>
                            <td>スリーサイズ</td>
                            <td>
                                B:
                                <?php if(empty($cast_fields['_krc_bust'][0])): ?>- <?php else: ?>
                                <?php echo esc_html($cast_fields['_krc_bust'][0]);?>
                                <?php endif; ?>
                                (
                                <?php if(empty($cast_fields['_krc_cups'][0])): ?>- <?php else: ?>
                                <?php echo esc_html($cast_fields['_krc_cups'][0]);?>
                                <?php endif; ?>
                                )
                                W:
                                <?php if(empty($cast_fields['_krc_waist'][0])): ?>- <?php else: ?>
                                <?php echo esc_html($cast_fields['_krc_waist'][0]);?>
                                <?php endif; ?>
                                H:
                                <?php if(empty($cast_fields['_krc_hips'][0])): ?>- <?php else: ?>
                                <?php echo esc_html($cast_fields['_krc_hips'][0]);?>
                                <?php endif; ?>
                            </td>
                        </tr>

                    </tbody>
                </table>
            </figure>
        </div>
        <h2 class="sub-section">コメント</h2>
        <div class="cast-pr"><?php the_content(); ?></div>
    </div>
</div>
<div class="cast-schedule">
    <h2 class="sub-section">スケジュール</h2>
    <?php singlecalendar(get_the_ID()); ?> //function.phpのsinglecalender()を呼び出す
</div>
<div class="wp-block-button is-style-fill">
    <a href="/schedule" class="wp-block-button__link">出勤情報はこちら</a>
</div>

<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.0.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/slick-carousel@1.8.1/slick/slick.css" />
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/slick-carousel@1.8.1/slick/slick.min.js"></script>

/*
* キャスト画像をスライド表示するjQuery
*/
<script type="text/javascript">
    jQuery(function($) {
        $('.top-slider').slick({
            slidesToShow: 1,
            slidesToScroll: 1,
            arrows: false,
            fade: true,
            asNavFor: '.thumbnail'
        });
        $('.thumbnail').slick({
            slidesToShow: 3,
            slidesToScroll: 1,
            asNavFor: '.top-slider',
            arrows: false,
            dots: true,
            centerMode: true,
            focusOnSelect: true
        });
    });

</script>
PHP
キャストの画像は Slick スライダー を使って表示しています。
キャストの画像が未設定の場合に表示する画像を、子テーマ内の「images フォルダ」に「no.jpg」という名前で保存しておいてください。

content-castlist.php

/*
* プラグインで設定した
*「カスタムフィールド」「画像」「タイプ管理」「グレード管理」「新人区分」
* を各変数に格納します
*/
<?php
	$cast_fields = get_post_custom(); //カスタムフィールドを全部取得
	$cast_screens = json_decode($cast_fields['_krc_cast_screens'][0]); //画像配列を用意
	$cast_type_terms = get_the_terms($post->ID, 'krc_type'); //タイプタクソノミーを取得
	$cast_grade_terms = get_the_terms($post->ID, 'krc_grade'); //グレードタクソノミーを取得
	$cast_new_terms = get_the_terms($post->ID, 'krc_new'); //新人区分タクソノミーを取得
?>

/*
* ブラウザがレンダリングできるようにHTMLに組み込みます
*/
<div class="cast">
    <a href="<?php the_permalink();?>">

        <figure class="cast-photo">
            <?php if( empty($cast_screens) ): ?>
            <img src="<?php echo get_stylesheet_directory_uri();?>/images/no.jpg" alt="<?php the_title();?>">
            <?php else: ?>
            <img src="<?php echo esc_url($cast_screens[0]);?>" alt="<?php the_title();?>">
            <?php endif;?>

            <?php if( empty($cast_new_terms) ): ?><?php else: ?>
            <span class="cast-new badge">New</span>
            <?php endif;?>

            <?php if ( $fncName != 'todaysCastHtml'): ?>
            <?php if (today_schedule(get_the_ID())):?>
            <span class="todays-cast badge">本日出勤</span>
            <?php endif;?>
            <?php endif;?>
        </figure>

        <figcaption class="text-center">

            <div class="cast-name">
                <?php echo esc_html($cast_fields['_krc_name'][0]);?>(<?php if(empty($cast_fields['_krc_age'][0])): ?> - <?php else: ?><?php echo esc_html($cast_fields['_krc_age'][0]);?><?php endif; ?>)
            </div>

            <div class="cast-size">
                T:<?php if(empty($cast_fields['_krc_tall'][0])): ?>- <?php else: ?><?php echo esc_html($cast_fields['_krc_tall'][0]);?>
                <?php endif; ?>
                B:<?php if(empty($cast_fields['_krc_bust'][0])): ?>- <?php else: ?><?php echo esc_html($cast_fields['_krc_bust'][0]);?><?php endif; ?>(<?php if(empty($cast_fields['_krc_cups'][0])): ?> - <?php else: ?><?php echo esc_html($cast_fields['_krc_cups'][0]);?><?php endif; ?>)
                W:<?php if(empty($cast_fields['_krc_waist'][0])): ?>- <?php else: ?><?php echo esc_html($cast_fields['_krc_waist'][0]);?>
                <?php endif; ?>
                H:<?php if(empty($cast_fields['_krc_hips'][0])): ?>- <?php else: ?><?php echo esc_html($cast_fields['_krc_hips'][0]);?>
                <?php endif; ?>
            </div>

        </figcaption>

    </a>
</div>
PHP
・新人キャストには「NEW」
・本日出勤のキャストには「本日出勤」と表示されるようにしています。

content-castschedule.php

/*
* プラグインで設定した
*「カスタムフィールド」「画像」「タイプ管理」「グレード管理」「新人区分」
* を各変数に格納します
*/
<?php
	$cast_fields = get_post_custom(); //カスタムフィールドを全部取得
	$cast_screens = json_decode($cast_fields['_krc_cast_screens'][0]); //画像配列を用意
	$cast_type_terms = get_the_terms($post->ID, 'krc_type'); //タイプタクソノミーを取得
	$cast_grade_terms = get_the_terms($post->ID, 'krc_grade'); //グレードタクソノミーを取得
	$cast_new_terms = get_the_terms($post->ID, 'krc_new'); //新人区分タクソノミーを取得
?>
/*
* ブラウザがレンダリングできるようにHTMLに組み込みます
*/
<div class="cast">
    <a href="<?php the_permalink();?>">

        <figure class="cast-photo">
            <?php if( empty($cast_screens) ): ?>
            <img src="<?php echo get_stylesheet_directory_uri(); ?>/images/no.jpg" alt="<?php the_title(); ?>">
            <?php else: ?>
            <img src="<?php echo $cast_screens[0]; ?>" alt="<?php the_title();?>">
            <?php endif;?>
            <?php if( empty($cast_new_terms) ): ?><?php else: ?>
            <span class="cast-new badge">New</span>
            <?php endif;?>
        </figure>

        <figcaption>
            <div class="cast-name">
                <?php echo esc_html($cast_fields['_krc_name'][0]);?>(<?php if(empty($cast_fields['_krc_age'][0])): ?> - <?php else: ?><?php echo esc_html($cast_fields['_krc_age'][0]);?><?php endif; ?>)
            </div>
            <div class="cast-size">
                T:<?php if(empty($cast_fields['_krc_tall'][0])): ?>- <?php else: ?><?php echo esc_html($cast_fields['_krc_tall'][0]);?>
                <?php endif; ?>

                B:<?php if(empty($cast_fields['_krc_bust'][0])): ?>- <?php else: ?><?php echo esc_html($cast_fields['_krc_bust'][0]);?><?php endif; ?>(<?php if(empty($cast_fields['_krc_cups'][0])): ?> - <?php else: ?><?php echo esc_html($cast_fields['_krc_cups'][0]);?><?php endif; ?>)
                W:<?php if(empty($cast_fields['_krc_waist'][0])): ?>- <?php else: ?><?php echo esc_html($cast_fields['_krc_waist'][0]);?>
                <?php endif; ?>
                H:<?php if(empty($cast_fields['_krc_hips'][0])): ?>- <?php else: ?><?php echo esc_html($cast_fields['_krc_hips'][0]);?>
                <?php endif; ?>
            </div>

            <div class="worktime">
                <i class="far fa-clock"></i>
                <?php
					if ($work['starttime'] !== '0') echo esc_html($work['starttime']); ?>
                -
                <?php if ($work['endtime'] !== '0') echo esc_html($work['endtime']);
					?>
            </div>

        </figcaption>
    </a>
</div>
PHP

content-todaycastlist.php

/*
* プラグインで設定した
*「カスタムフィールド」「画像」「タイプ管理」「グレード管理」「新人区分」
* を各変数に格納します
*/
<?php
$cast_fields = get_post_custom(); //カスタムフィールドを全部取得
$cast_screens = json_decode($cast_fields['_krc_cast_screens'][0]); //画像配列を用意
$cast_type_terms = get_the_terms($post->ID, 'krc_type'); //タイプタクソノミーを取得
$cast_grade_terms = get_the_terms($post->ID, 'krc_grade'); //グレードタクソノミーを取得
$cast_new_terms = get_the_terms($post->ID, 'krc_new'); //新人区分タクソノミーを取得
?>
/*
* ブラウザがレンダリングできるようにHTMLに組み込みます
*/
<div class="cast">
    <a href="<?php the_permalink();?>">

        <figure class="cast-photo">
            <?php if( empty($cast_screens) ): ?>
            <img src="<?php echo get_stylesheet_directory_uri();?>/images/no.jpg" alt="<?php the_title();?>">
            <?php else: ?>
            <img src="<?php echo esc_url($cast_screens[0]);?>" alt="<?php the_title();?>">
            <?php endif;?>
            <?php if( empty($cast_new_terms) ): ?><?php else: ?>
            <span class="cast-new badge">New</span>
            <?php endif;?>
        </figure>

        <figcaption>
            <div class="cast-name">
                <?php echo esc_html($cast_fields['_krc_name'][0]);?>(
                <?php if(empty($cast_fields['_krc_age'][0])): ?>- <?php else: ?>
                <?php echo esc_html($cast_fields['_krc_age'][0]);?>
                <?php endif; ?>)
            </div>
            <div class="cast-size">
                T:<?php if(empty($cast_fields['_krc_tall'][0])): ?>- <?php else: ?><?php echo esc_html($cast_fields['_krc_tall'][0]);?>
                <?php endif; ?>
                B:<?php if(empty($cast_fields['_krc_bust'][0])): ?>- <?php else: ?><?php echo esc_html($cast_fields['_krc_bust'][0]);?><?php endif; ?>(<?php if(empty($cast_fields['_krc_cups'][0])): ?> - <?php else: ?><?php echo esc_html($cast_fields['_krc_cups'][0]);?><?php endif; ?>)
                W:<?php if(empty($cast_fields['_krc_waist'][0])): ?>- <?php else: ?><?php echo esc_html($cast_fields['_krc_waist'][0]);?>
                <?php endif; ?>
                H:<?php if(empty($cast_fields['_krc_hips'][0])): ?>- <?php else: ?><?php echo esc_html($cast_fields['_krc_hips'][0]);?>
                <?php endif; ?>
            </div>

            <!-- 出勤時間を表示 -->
            <div class="worktime">
                <i class="far fa-clock"></i>
                <?php
                date_default_timezone_set('Asia/Tokyo');
                $today = getdate(); 

                if($today['hours'] >= 0 and $today['hours'] < 5) {//0時〜5時の表示
                    $today = strtotime(date("Y-m-d", strtotime("today")));
                    echo '<span class="before5am">';

                    for ($i = 0; $i <= 0; $i++) {//--- ループここから ---
                        $y = date('D', strtotime('+'.$i.'-1 day', $today));
                        if ( date('Y-m-d', strtotime('+'.$i.'-1 day', $today)) == $day ) $y = 'target';
                        echo '';	
                        if ( $casttime = today_schedule($id, date('Y-m-d', strtotime('+'.$i.'-1 day', $today))) ) {
                            if ($casttime['starttime'] !== '0') echo esc_html($casttime['starttime']);
                            echo ' - ';
                            if ($casttime['endtime'] !== '0') echo esc_html($casttime['endtime']);
                        }
                        echo '</span>';
                    }//--- ループここまで ---
                }  else {
                    date_default_timezone_set('Asia/Tokyo');
                    $today = strtotime(date("Y-m-d", strtotime("today"))); //5時以降の表示
                    echo '<span class="after5am">';

                    for ($i = 0; $i <= 0; $i++) {//--- ループここから ---
                        $y = date('D', strtotime('+'.$i.' day', $today));
                        if ( date('Y-m-d', strtotime('+'.$i.' day', $today)) == $day ) $y = 'target';
                        echo '';	
                        if ( $casttime = today_schedule($id, date('Y-m-d', strtotime('+'.$i.' day', $today))) ) {
                            if ($casttime['starttime'] !== '0') echo esc_html($casttime['starttime']);//入り時間
                            echo ' - ';
                            if ($casttime['endtime'] !== '0') echo esc_html($casttime['endtime']);//上がり時間
                        }
                        echo '</span>';
                    } //--- ループここまで ---
                }
                ?>
            </div>
        </figcaption>
    </a>
</div>
PHP
日付の切り替えは朝の 5 時に行われます。

single-cast.php

<?php get_header(); ?>

<div id="primary" class="content-area">

    <?php while ( have_posts() ) : the_post(); ?>

    <?php get_template_part('content',('cast'));?> //content-cast.phpを呼び出す

    <?php endwhile; // End of the loop. ?>

</div><!-- #primary -->

<?php
get_sidebar();
get_footer();
PHP

functions.phpに追加

<?php
/*** 個人ページに表示するスケジュール ***/
function singlecalendar($id) {
	$week = array("", "", "", "", "", "", "");
	$today = strtotime(date("Y-m-d", strtotime("+3 hour")));
	echo '<div class="krc_calendar">';
	for ($i = 0;$i <= 6;$i++)
	{
		$yy = date('w', strtotime('+' . $i . ' day'));
		$y = date('D', strtotime('+' . $i . ' day', $today));
		if (date('Y-m-d', strtotime('+' . $i . ' day', $today)) == $day) $y = 'target';
		echo '<dl><dt class="' . mb_strtolower($y) . '">' . strtoupper(date('n/j(' . $week[$yy] . ')', strtotime('+' . $i . ' day', $today))) . '</dt>';
		if ($casttime = today_schedule($id, date('Y-m-d', strtotime('+' . $i . ' day', $today)))) //today_schedule()を呼び出して本日の出勤情報の有無を判断
		{
			echo '<dd>';
			if ($casttime['starttime'] !== '0') echo esc_html($casttime['starttime']);
			echo ' - ';
			if ($casttime['endtime'] !== '0') echo esc_html($casttime['endtime']);
			echo '</dd></dl>';
		}
		else
		{
			echo '<dd>-</dd></dl>';
		}
	}
	echo '</div>';
}
 
/*** 本日の出勤確認 ***/
function today_schedule($id, $day = '')
{
	$day = $day != '' ? $day : date("Y-m-d", strtotime("+3 hour"));
	$day = htmlentities($day, ENT_QUOTES, 'utf-8');
	$works = outschedule($day);
	if ($works && $works != 'rest' && array_key_exists($id, $works))
	{
		return $works[$id];
	}
	else
	{
		return false;
	}
}
 
/*** スケジュール ***/
function outschedule($day) { //DBから該当の日付のデータを取得
	global $wpdb;
	$table_name = $wpdb->prefix . 'krc_schedules';
	$schedules = $wpdb->get_var(
		$wpdb->prepare("SELECT work FROM $table_name WHERE day = %s AND status = %d", $day, 0)
	);
	$works = unserialize($schedules);
	return $works; //配列にして返す
}

/* ショートコード[scheduleshtml]の関数 */
function schedulesHtml() {
	ob_start();
	$day = isset($_GET["works"]) ? $_GET['works'] : date("Y-m-d");
	$works = outschedule($day);
	$len = 6; //+1
    $week = array("", "", "", "", "", "", "");
 
	echo '<nav class="week_calendar"><ul>';
	for ($i = 0;$i <= $len;$i++)
	{
		$yy = date('w', strtotime('+' . $i . ' day'));
		$y = date('D', strtotime('+' . $i . ' day'));
		if (date('Y-m-d', strtotime('+' . $i . ' day')) == $day) $y = 'target';
		echo '<li class="' . mb_strtolower($y) . ' nav-contents"><a href="' . home_url('/') . '/schedule/?works=' . date('Y-m-d', strtotime('+' . $i . ' day')) . '">' . strtoupper(date('n/j (' . $week[$yy] . ')', strtotime('+' . $i . ' day'))) . '</a></li>';
	}
	echo '</ul></nav>';
	$w = date('w', strtotime($day));
	// echo '<div class="wp-block-group__inner-container home-block">';
	echo '<h2>' . date('n/j', strtotime($day));
	echo '(' . $week[$w] . ')';
	echo 'の出勤スケジュール</h2>';
 
	if (!$works)
	{
		//予定がない場合
		echo '<br>';
	}
	else if ($works != 'rest')
	{
		echo '<div class="row">';
		//postid順に配列に入っているのでs_order順にした配列を作る
		$works_array = array();
		foreach ($works as $id => $val)
		{
			$works_array[$val["s_order"]] = $id;
		}
		ksort($works_array);
		foreach ($works_array as $rder => $id)
		{
			$args = array(
				'post_type' => 'cast',
				'post__in' => array(
					$id
				) ,
			);
			query_posts($args);
			while (have_posts()):
				the_post();
				set_query_var('work', $works[$id]);
				get_template_part('content', ('castschedule'));
			endwhile;
			wp_reset_query();
 
		}
		echo '</div>';
	}
	else
	{
		//休み
		echo '定休日';
	}
	return ob_get_clean();
}
add_shortcode('scheduleshtml', 'schedulesHtml'); //schedulesHtml()をショートコード[scheduleshtml]に登録
 
 
/*** TOPページ等に本日出勤キャストを表示 ***/
/* ショートコード[todayscasthtml]の関数 */
function todaysCastHtml ($day = '') { //本日の出勤
	ob_start();
	date_default_timezone_set('Asia/Tokyo');
	$time9 =  - 5;//5時に次の日のスケジュールに切り替わる仕様 .$time9.  date_i18n
	$day = $day != '' ? $day : date("Y-m-d",strtotime("+".$time9." hour"));
	$works = outschedule($day);
	addSchedules($works); //addSchedules()を呼び出す
	return ob_get_clean();
}

function addSchedules($works) {
	$schedule = 'schedule';
	if (!$works) {
		//予定がない場合
		echo '<div>更新中</div>';
	} else if ( $works !='rest' ) {
		$works_array = array();
		foreach($works as $id => $val){
			$works_array[$val["s_order"]] = array(
			'id'=> $id,
			'time' => $val
			);
		}
		ksort($works_array);
		foreach ($works_array as $id => $work) {
			$args = array(
			'post_type' => 'cast',
			'post__in' => array($work['id']),
			'orderby' => 'post__in'
			);
			//$test =
			query_posts($args);
			//printR($test);
		
			while ( have_posts() ) : the_post();
			set_query_var( 'schedule', $work['time'] );
			get_template_part( 'content', 'todaycastlist' ); //content-castlist.phpは用意しておいてください。
			endwhile;
			wp_reset_query();
		}
	}
	else {
		//休み
		echo '<div>本日定休日です</div>';
	}
}
add_shortcode('todayscasthtml', 'todaysCastHtml'); //todaysCastHtml()をショートコード[todayscasthtml]に登録
 
 
/*** 新人キャストショートコード ***/
function outNewType () {
	ob_start();
 
	$args = array(
	'post_type' => 'cast',
	'posts_per_page' => -1,
	'tax_query' => array(
		'relation' => 'AND',
		array(
			'taxonomy' => 'krc_new',
			'field' => 'slug',
			'terms' => "新人",
		)
	));
 
	query_posts($args);
	if ( have_posts() ) :
		while ( have_posts() ) :
			the_post();
			get_template_part( 'content', 'castlist' ); //content-castlist.phpは用意しておいてください。
		endwhile;
	endif;
 
	wp_reset_query();
	return ob_get_clean();
 
}
add_shortcode('newcasthtml', 'outNewType'); //outNewType()をショートコード[newcasthtml]に登録
 
 
/*** 翌日5時までを本日として表示させる ***/
function today() {
	date_default_timezone_set('Asia/Tokyo');
	$today = getdate();
	if($today['hours'] >= 0 and $today['hours'] < 5) {//0時〜5時の表示
	echo date('n/j', strtotime('-1 day'));//日付
	} else {//5時以降の表示
		echo date('n/j');//日付
	}
}
add_shortcode('today', 'today'); //today()をショートコード[today]に登録
 
 
 
/*** キャスト一覧をフロントページに表示 ***/
function castList() {
$args = array(
'posts_per_page' => 8, // 表示する投稿数
'post_type' => 'cast'
);
$my_posts = get_posts($args);
 
query_posts($args);
if ( have_posts() ) :
	while ( have_posts() ) :
		the_post();
		get_template_part( 'content', 'castlist' ); //content-castlist.phpは用意しておいてください。
	endwhile;
endif;
 
wp_reset_postdata();
}
?>
PHP
主なショートコードは以下のとおりです。
・スケジュールページ:[scheduleshtml] ・本日出勤キャストページ:[todayscasthtml] / [today] ・新人キャストページ:[newcasthtml]
これらの関数を functions.php に記述しています。

その他

キャスト一覧ページのページヘッダータイトル、デフォルトは「在籍女性」です。プラグインフォルダ内の class-krc-model-casts.php で変更できます。

class-krc-model-casts.php 一部変更

<?php
//キャストカスタム投稿作成
public function create_cast_post_type () {
	$labels = array(
	    //'name'                  => __( '在籍女性', 'krc' ),
	      'name'                  => __( 'キャスト一覧', 'krc' ),
PHP

krc-cast-managerを組み込んでできたサイト

最低限の装飾でデモサイトを作ってみました。

キャスト一覧ページ( archive-cast.php )

新人キャストページ
新人キャストページ
キャスト一覧ページは「サイト URL/cast」にあります。
content-castlist.php から引いてきて、archive-cast.php で表示しています。

スケジュールページ( single-cast.php )

スケジュールはページ下部に表示されます

個別キャスト
個別キャスト
スケジュールページは固定ページとして作成しています。
そのページ内で、ショートコード [scheduleshtml] を使いスケジュールを呼び出しています。

個別キャストページ( [scheduleshtml] )

キャスト情報はページ上部に表示されます

個別キャスト
個別キャスト
content-cast.php から引いてきて、single-cast.php で表示しています。
下部のスケジュールは、functions.php で定義した関数を呼び出しています。
キャストの画像は Slick スライダーを使って表示しています。

本日出勤キャスト表示( [todayscasthtml] )

本日出勤
本日出勤
functions.php で作ったショートコードを呼び出しています。
トップページなど、好きな場所に表示できます。

新人キャスト表示( [newcasthtml] )

キャスト一覧ページ
functions.php で作ったショートコードを呼び出しています。
トップページなど、好きな場所に表示できます。

まとめ

以上がWordPress のテンプレート構造、プラグイン「krc-cast-manager」の導入方法の説明になります。

無料在席キャスト管理システム「krc-cast-manager」を使いこなせれば、ブログサイト制作だけでなく、スタッフ管理やセミナーのスケジュール管理にも応用できます。

今回はプラグインを動かすところまでに留めたため、レイアウトは Bootstrap でざっくり指定しています。

機会があれば、ElementorやDiviなどのNoCodeツールと連携してリッチなデザインにしてみたいです。
WEBさん
WEBさん

「うちの業態でもこれ使えるか判断したい」「不具合に当たって動かない」という段階でしたら、プラグインの中身まで踏み込んでお手伝いできます。

コメントを残す

メールアドレスは公開されません。* は必須項目です。

CAPTCHA