コンテンツ制限機能 仕様書¶
作成日: 2025-12-29
ステータス: 仕様確定
プラグイン名: inportal-content-restriction
1. 概要¶
1.1 目的¶
北日本造船株式会社の社員と外部会社ユーザーで、閲覧可能なコンテンツ・機能を分けるためのアクセス制御機能。
1.2 対象ユーザー分類¶
| 分類 | 判定条件 | 備考 |
|---|---|---|
| 社内ユーザー | ipa_company = 北日本造船㈱ |
判定値は管理画面で変更可能 |
| 外部ユーザー | 上記以外の全ユーザー | グループ会社、協力会社など |
1.3 前提条件¶
- 未ログインユーザーは全コンテンツ閲覧不可(既存のサイトパスワード保護で対応済み)
- ログイン済みユーザーのみが本機能の対象
2. 機能一覧¶
| 機能 | 説明 |
|---|---|
| 投稿/ページ単位の制限 | 投稿・固定ページごとに「社内のみ」設定 |
| 一括設定 | 投稿一覧画面で複数投稿を一括設定 |
| メニュー項目の制限 | ドロワーメニューの機能別表示/非表示 |
| 直接URLアクセス防止 | 制限コンテンツへの直接アクセス時はリダイレクト |
| 管理画面設定 | 判定値・メニュー設定を管理画面で変更可能 |
3. 投稿/ページ単位の制限¶
3.1 設定方法¶
投稿編集画面¶
┌──────────────────────────────────────┐
│ 公開 │
├──────────────────────────────────────┤
│ ステータス: 公開済み │
│ 公開日: 2025年12月29日 │
│ │
│ ☑ 社内のみ表示 │
│ (外部ユーザーには非表示になります) │
└──────────────────────────────────────┘
投稿一覧画面¶
┌────────────────────────────────────────────────────────────────┐
│ 一括操作 ▼ [適用] □ タイトル 公開範囲 日時 │
├────────────────────────────────────────────────────────────────┤
│ ☑ 社内のみに設定 □ 記事タイトル1 🔒社内のみ 12/28 │
│ ☐ 全員に公開 □ 記事タイトル2 🌐全員 12/27 │
│ □ 記事タイトル3 🌐全員 12/26 │
└────────────────────────────────────────────────────────────────┘
3.2 データ構造¶
| 項目 | 値 |
|---|---|
| メタキー | _inportal_internal_only |
| 制限あり | 1 |
| 制限なし | 空(メタなし) |
3.3 表示制御ロジック¶
// 投稿クエリフィルター(一覧・検索結果)
add_action('pre_get_posts', function($query) {
if (is_admin() || !$query->is_main_query()) return;
$user_company = get_user_meta(get_current_user_id(), 'ipa_company', true);
$internal_company = get_option('icr_internal_company', '北日本造船㈱');
$is_internal = ($user_company === $internal_company);
if (!$is_internal) {
$meta_query = $query->get('meta_query') ?: [];
$meta_query[] = [
'relation' => 'OR',
['key' => '_inportal_internal_only', 'compare' => 'NOT EXISTS'],
['key' => '_inportal_internal_only', 'value' => '1', 'compare' => '!='],
];
$query->set('meta_query', $meta_query);
}
});
// 単一投稿アクセス制御
add_action('template_redirect', function() {
if (!is_singular()) return;
$post_id = get_queried_object_id();
$is_internal_only = get_post_meta($post_id, '_inportal_internal_only', true);
if ($is_internal_only === '1') {
$user_company = get_user_meta(get_current_user_id(), 'ipa_company', true);
$internal_company = get_option('icr_internal_company', '北日本造船㈱');
if ($user_company !== $internal_company) {
// 専用エラーページへリダイレクト
wp_redirect(home_url('/?content_restricted=1'));
exit;
}
}
});
3.4 エラーページ¶
制限コンテンツへの直接アクセス時は、専用のエラーページを表示:
┌──────────────────────────────────────────────────┐
│ │
│ このページは表示できません │
│ │
│ [ホームへ戻る] │
│ │
└──────────────────────────────────────────────────┘
※「アクセス権限がありません」のような表現は避け、柔らかい表現を使用
3.5 ホーム画面のUI要素制御¶
ドロワーメニューだけでなく、以下のホーム画面要素も制限対象:
| 要素 | 説明 |
|---|---|
| ダッシュボードカード | 出勤ボード、ポイント表示など |
| アクショングリッド | 機能一覧のグリッドアイテム |
| ドロワーメニュー | サイドメニューのリンク |
すべての導線から制限機能を非表示にする
4. メニュー項目の制限¶
4.1 対象メニュー項目¶
| ID | メニュー項目 | デフォルト設定 | 備考 |
|---|---|---|---|
home |
ホーム | 全員 | |
news |
お知らせ一覧 | 全員 | |
board |
出勤ボード | 社内のみ | |
checkin |
チェックイン | 社内のみ | 将来拡張予定 |
reserve |
会議室予約 | 社内のみ | |
times |
社内報 | 社内のみ | KITA Times |
knowledge |
ナレッジヤード | 社内のみ | 外部リンク |
point |
ポイント管理 | 全員 | |
suggestion |
目安箱 | 全員 | 新規追加 |
instagram |
公式Instagram | 全員 | 外部リンク |
4.2 管理画面設定¶
設定 → コンテンツ制限
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
■ 基本設定
社内ユーザーの判定値
┌────────────────────────────────────────────┐
│ 北日本造船㈱ │
└────────────────────────────────────────────┘
※ユーザーメタ「ipa_company」の値と比較します
■ メニュー項目の公開設定
┌──────────────────────────────────────────────────────────┐
│ 機能名 │ 社内のみ │ 全員 │ │
├──────────────────────────────────────────────────────────┤
│ ホーム │ ○ │ ● │ │
│ お知らせ一覧 │ ○ │ ● │ │
│ 出勤ボード │ ● │ ○ │ │
│ チェックイン │ ● │ ○ │ ※将来拡張予定 │
│ 会議室予約 │ ● │ ○ │ │
│ 社内報 │ ● │ ○ │ │
│ ナレッジヤード │ ● │ ○ │ │
│ ポイント管理 │ ○ │ ● │ │
│ 目安箱 │ ○ │ ● │ │
│ 公式Instagram │ ○ │ ● │ │
└──────────────────────────────────────────────────────────┘
[変更を保存]
4.3 オプション構造¶
// wp_options テーブル
$options = [
'icr_internal_company' => '北日本造船㈱', // 社内判定値
'icr_menu_restrictions' => [
'home' => 'all', // 'all' = 全員, 'internal' = 社内のみ
'news' => 'all',
'board' => 'internal',
'checkin' => 'internal',
'reserve' => 'internal',
'times' => 'internal',
'knowledge' => 'internal',
'point' => 'all',
'suggestion' => 'all',
'instagram' => 'all',
],
];
4.4 テーマ側の実装¶
// template-parts/app-header.php
// プラグインからヘルパー関数を使用
$is_internal_user = icr_is_internal_user();
$menu_restrictions = get_option('icr_menu_restrictions', []);
// メニュー項目の表示判定
function icr_can_show_menu($menu_id) {
$restrictions = get_option('icr_menu_restrictions', []);
$restriction = $restrictions[$menu_id] ?? 'all';
if ($restriction === 'all') {
return true;
}
return icr_is_internal_user();
}
// 使用例
<?php if (icr_can_show_menu('board')): ?>
<li class="app-drawer__item">
<a href="<?php echo esc_url(home_url('/?ipa_board_view=1')); ?>" ...>
出勤ボード
</a>
</li>
<?php endif; ?>
5. ヘルパー関数¶
プラグインが提供するグローバル関数:
/**
* 現在のユーザーが社内ユーザーかどうか判定
*
* @return bool
*/
function icr_is_internal_user(): bool {
if (!is_user_logged_in()) {
return false;
}
$user_company = get_user_meta(get_current_user_id(), 'ipa_company', true);
$internal_company = get_option('icr_internal_company', '北日本造船㈱');
return $user_company === $internal_company;
}
/**
* 指定メニュー項目を表示してよいか判定
*
* @param string $menu_id メニューID
* @return bool
*/
function icr_can_show_menu(string $menu_id): bool {
$restrictions = get_option('icr_menu_restrictions', []);
$restriction = $restrictions[$menu_id] ?? 'all';
if ($restriction === 'all') {
return true;
}
return icr_is_internal_user();
}
/**
* 指定投稿が社内のみかどうか判定
*
* @param int $post_id 投稿ID
* @return bool
*/
function icr_is_internal_only_post(int $post_id): bool {
return get_post_meta($post_id, '_inportal_internal_only', true) === '1';
}
6. 将来拡張予定¶
6.1 チェックイン機能の分離¶
現在「チェックイン」は一つのメニュー項目ですが、将来的に以下のように分離予定:
| 場所タイプ | 説明 | 公開設定 |
|---|---|---|
| 会議室 (room) | 本社・工場の会議室 | 社内のみ |
| 現場 (site) | 作業現場・工場ゲート | 全員 |
実装方針:
1. wp_locations テーブルに is_internal_only カラムを追加
2. 場所ごとに公開設定を持たせる
3. チェックイン画面で場所タイプ選択時にフィルタリング
6.2 カテゴリベースの制限¶
将来的に、投稿カテゴリ単位での制限も検討:
7. 管理画面メニュー構成¶
8. セキュリティ考慮事項¶
| リスク | 対策 |
|---|---|
| 直接URLアクセス | template_redirect フックでリダイレクト |
| REST API アクセス | 必要に応じてAPIにも同様のフィルター適用 |
| キャッシュ問題 | ユーザー別キャッシュ or キャッシュ無効化 |
| 検索結果漏洩 | pre_get_posts で除外 |
9. テスト項目¶
- [ ] 社内ユーザーで制限コンテンツが表示される
- [ ] 外部ユーザーで制限コンテンツが非表示
- [ ] 外部ユーザーで直接URLアクセス時にリダイレクト
- [ ] 投稿編集画面でチェックボックスが機能する
- [ ] 投稿一覧で一括設定が機能する
- [ ] 管理画面で判定値を変更できる
- [ ] 管理画面でメニュー制限を変更できる
- [ ] ドロワーメニューで制限項目が非表示になる