
<?php

function get_tag_class() {
    $tags = get_the_tags();
    $tag_class = '';

    if ($tags) {
        foreach ($tags as $tag) {
            if ($tag->name === 'お知らせ') {
                $tag_class .= ' tag-notice';
            } elseif ($tag->name === '活動報告') {
                $tag_class .= ' tag-report';
            } elseif ($tag->name === '重要') {
                $tag_class .= ' tag-important';
            } elseif ($tag->name === '会員限定') {
                $tag_class .= ' tag-member';
            }
            
            // 今後のタグの増減や名称変更に対応する場合は、ここに追加の条件分岐を行います
        }
    }

    return $tag_class;
}

// タグのドロップダウンメニューを表示する
function custom_tag_dropdown() {
    // タグの一覧を取得
    $tags = get_tags();
    
    if ( $tags ) {
        // ドロップダウンメニューのHTMLを生成
        $options = '<option value="">タグを選択</option>';
        foreach ( $tags as $tag ) {
            $options .= '<option value="' . $tag->term_id . '">' . $tag->name . '</option>';
        }
        
        // ドロップダウンメニューを出力
        echo '<select name="tag-dropdown">' . $options . '</select>';
    }
}

// パンくずを出力
/* function custom_breadcrumb() {
    echo '<ul class="breadcrumb">';
  
    if (!is_front_page()) {
      echo '<li><a href="';
      echo esc_url(home_url('/'));
      echo '">Home</a></li>';
  
      if (is_category() || is_single()) {
        echo '<li>';
        the_category(' <span class="breadcrumb-separator">></span> ');
        if (is_single()) {
          echo '<span class="breadcrumb-separator">></span>';
          echo '<li>';
          the_title();
          echo '</li>';
        }
      } elseif (is_page()) {
        echo '<li>';
        echo the_title();
        echo '</li>';
      } elseif (is_page('members')) {
        echo '<li>会員専用ページ</li>';
      }
    }
  
    echo '</ul>';
  } */



// プライバシーポリシーのショートコード作成
  function privacy_policy_link_shortcode() {
    return '<a href="' . esc_url( home_url( 'privacy-policy' ) ) . '">プライバシーポリシー</a>';
}


add_shortcode( 'privacy_policy_link', 'privacy_policy_link_shortcode' );
// 投稿名を「お知らせ」に変更
function Change_menulabel() {
	global $menu;
	global $submenu;
	$name = 'お知らせ';
	$menu[5][0] = $name;
	$submenu['edit.php'][5][0] = $name.'一覧';
	$submenu['edit.php'][10][0] = '新しい'.$name;
}
function Change_objectlabel() {
	global $wp_post_types;
	$name = 'お知らせ';
	$labels = &$wp_post_types['post']->labels;
	$labels->name = $name;
	$labels->singular_name = $name;
	$labels->add_new = _x('追加', $name);
	$labels->add_new_item = $name.'の新規追加';
	$labels->edit_item = $name.'の編集';
	$labels->new_item = '新規'.$name;
	$labels->view_item = $name.'を表示';
	$labels->search_items = $name.'を検索';
	$labels->not_found = $name.'が見つかりませんでした';
	$labels->not_found_in_trash = 'ゴミ箱に'.$name.'は見つかりませんでした';
}
add_action( 'init', 'Change_objectlabel' );
add_action( 'admin_menu', 'Change_menulabel' );


// ページネーション
function fix_custom_query_paged($query) {
    if (is_admin() || !$query->is_main_query()) {
      return;
    }
  
    if ($query->is_paged()) {
      $paged = $query->get('paged');
      if (!$paged) {
        $query->set('paged', 1);
      }
    }
  }
  add_action('pre_get_posts', 'fix_custom_query_paged');



  // ログイン時のリダイレクト先を指定
add_action( 'wpmem_register_redirect', 'my_reg_redirect' );

function my_reg_redirect( $fields ) {
    wp_redirect( home_url( '/members/' ) );
    exit();
}

  // ファイル送信ボタンのスタイル変更
  function change_cf7_file_upload_button_text() {
    return 'ファイルを選択'; // ボタンに表示するテキストを変更
}
add_filter('wpcf7_upload_temp_dir', 'change_cf7_file_upload_button_text');








// カスタムタクソノミーを投稿ページの文書設定パネルに表示
/* function custom_taxonomy_metabox() {
    add_meta_box(
        'custom_taxonomy_metabox',
        'カスタムタクソノミー',
        'render_custom_taxonomy_metabox',
        'program', // タクソノミーを表示する投稿タイプを指定
        'side', // パネルの表示位置（例: 'normal', 'side', 'advanced'）
        'default' // パネルの優先度（例: 'high', 'core', 'default', 'low'）
    );
} */

/* function render_custom_taxonomy_metabox($post) {
    // タクソノミーの表示コードをここに追加
    // 例: カスタムタクソノミーのチェックボックスリストを表示するコード
    $terms = get_terms(array(
        'taxonomy' => 'program_cate', // カスタムタクソノミーのスラッグを指定
        'hide_empty' => false,
    ));
    
    if ($terms) {
        foreach ($terms as $term) {
            $checked = '';
            if (has_term($term->term_id, 'program_cate', $post)) {
                $checked = 'checked';
            }
            
            echo '<label><input type="checkbox" name="program_cate[]" value="' . $term->term_id . '" ' . $checked . '>' . $term->name . '</label><br>';
        }
    }
}

add_action('add_meta_boxes', 'custom_taxonomy_metabox');
 */


// カスタムタクソノミーの保存
function save_custom_taxonomy($post_id) {
    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
        return;
    }
    
    if (isset($_POST['program_cate'])) {
        wp_set_post_terms($post_id, $_POST['program_cate'], 'program_cate', false);
    }
}

add_action('save_post', 'save_custom_taxonomy');


// プログラムの確認
function custom_program_post_type() {
    $args = array(
        'public' => true,
        'label' => 'Program', // カスタム投稿タイプのラベル
        'supports' => array('title', 'editor', 'thumbnail'),
        'rewrite' => array('slug' => 'program'), // パーマリンクのスラッグ
    );
    register_post_type('program', $args);
}
add_action('init', 'custom_program_post_type');

// カスタムタクソノミーの登録
function custom_program_cate_taxonomy() {
    $args = array(
        'label' => 'Program Category', // カスタムタクソノミーのラベル
        'hierarchical' => true,
        'rewrite' => array('slug' => 'program_cate'), // パーマリンクのスラッグ
    );
    register_taxonomy('program_cate', 'program', $args);
}
add_action('init', 'custom_program_cate_taxonomy');






// 画像サポート（journal を含む）＋表紙用サイズ（任意）
add_action('after_setup_theme', function () {
  add_theme_support('post-thumbnails', ['post','page','journal']);
  add_image_size('journal-cover', 800, 1100, true);
});

// 学術雑誌（journal）CPT：/members/journals/ に配置
add_action('init', function () {
  register_post_type('journal', [
    'label'               => '学術雑誌',
    'public'              => true,
    'publicly_queryable'  => true,
    'show_ui'             => true,
    'show_in_rest'        => true,
    'menu_icon'           => 'dashicons-book-alt',
    'has_archive'         => 'members/journals', // ← 一覧URL
    'rewrite'             => [
      'slug'       => 'members/journals',       // ← 個別URL
      'with_front' => false,
      'pages'      => true,
      'feeds'      => false,
    ],
    'supports'            => ['title','editor','excerpt','thumbnail','revisions'],
  ]);
}, 5);

// テーマ切り替え時にリライトルール更新（保険）
add_action('after_switch_theme', function () {
  flush_rewrite_rules();
});

// 旧 /journals/slug/ → 新 /members/journals/slug/ へ 301（任意）
add_action('template_redirect', function () {
  $req = trim(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH), '/');
  if (preg_match('#^journals/([^/]+)/?$#', $req, $m)) {
    wp_redirect(home_url('/members/journals/' . $m[1] . '/'), 301);
    exit;
  }
});

// journal アーカイブの表示件数（任意）
add_action('pre_get_posts', function ($q) {
  if (!is_admin() && $q->is_main_query() && $q->is_post_type_archive('journal')) {
    $q->set('posts_per_page', 12);
  }
});


// ===================== 目次（PDF）メタボックス =====================
add_action('add_meta_boxes', function () {
  add_meta_box('journal_toc_meta', '目次（PDF）', function ($post) {
    wp_nonce_field('save_journal_toc', 'journal_toc_nonce');
    if (function_exists('wp_enqueue_media')) wp_enqueue_media();

    $toc = get_post_meta($post->ID, '_journal_toc', true);
    if (!is_array($toc)) $toc = [];

    echo '<style>
      .jtoc-row{
        display:grid;
        grid-template-columns:1fr auto 120px auto;
        gap:8px;
        align-items:start;
        margin-bottom:8px
      }
      .jtoc-row textarea{width:100%;min-height:3.6em}
      .jtoc-row input[type=text]{width:100%}
      .jtoc-head{
        display:grid;
        grid-template-columns:1fr auto 120px auto;
        gap:8px;
        font-weight:700;
        margin:4px 0
      }
    </style>';

    echo '<div class="jtoc-head"><div>表示名</div><div>PDF</div><div>ページ表記</div><div></div></div>';
    echo '<div id="jtoc-list">';

    foreach ($toc as $i => $item) {
      $title = isset($item['title']) ? $item['title'] : '';
      $aid   = isset($item['att_id']) ? (int)$item['att_id'] : 0;
      $pages = isset($item['pages']) ? $item['pages'] : '';
      $name  = $aid ? (get_the_title($aid) ?: basename((string)wp_get_attachment_url($aid))) : '未選択';
      printf('
        <div class="jtoc-row" data-index="%1$d">
          <textarea name="journal_toc[%1$d][title]" rows="3" placeholder="例：
演題：・・・
所属：・・・
氏名：・・・">%2$s</textarea>
          <span class="pdf-name">%3$s</span>
          <input type="text" name="journal_toc[%1$d][pages]" value="%4$s" placeholder="例：pp.1–10" />
          <span>
            <input type="hidden" class="pdf-id" name="journal_toc[%1$d][att_id]" value="%5$d" />
            <button type="button" class="button select-pdf">選択</button>
            <button type="button" class="button link-button clear-pdf">解除</button>
            <button type="button" class="button link-button remove-row">削除</button>
          </span>
        </div>',
        (int)$i,
        esc_textarea($title),
        esc_html($name),
        esc_attr($pages),
        (int)$aid
      );
    }
    echo '</div>';
    echo '<p><button type="button" class="button" id="jtoc-add">＋ 項目を追加</button></p>';

    // テンプレ（新規行）
    echo '<script type="text/html" id="jtoc-row-tpl">
      <div class="jtoc-row" data-index="__i__">
        <textarea name="journal_toc[__i__][title]" rows="3" placeholder="例：
演題：・・・
所属：・・・
氏名：・・・"></textarea>
        <span class="pdf-name">未選択</span>
        <input type="text" name="journal_toc[__i__][pages]" value="" placeholder="例：pp.1–10" />
        <span>
          <input type="hidden" class="pdf-id" name="journal_toc[__i__][att_id]" value="" />
          <button type="button" class="button select-pdf">選択</button>
          <button type="button" class="button link-button clear-pdf">解除</button>
          <button type="button" class="button link-button remove-row">削除</button>
        </span>
      </div>
    </script>';

    // JS
    ?>
    <script>
    (function($){
      let i = <?php echo count($toc); ?>;
      const $list = $('#jtoc-list');
      const tpl = document.getElementById('jtoc-row-tpl').text;

      $('#jtoc-add').on('click', function(){
        $list.append(tpl.replace(/__i__/g, i++));
      });

      let frame;
      $list.on('click', '.select-pdf', function(){
        const $row = $(this).closest('.jtoc-row');
        if (frame) frame.close();
        frame = wp.media({
          title: 'PDFを選択',
          button: { text: 'このPDFを使用' },
          multiple: false,
          library: { type: 'application' }
        });
        frame.on('select', function(){
          const file = frame.state().get('selection').first().toJSON();
          if (file.mime !== 'application/pdf') { alert('PDFを選択してください'); return; }
          $row.find('.pdf-id').val(file.id);
          $row.find('.pdf-name').text(file.filename || file.title || '選択済み');
        });
        frame.open();
      });

      $list.on('click', '.clear-pdf', function(){
        const $row = $(this).closest('.jtoc-row');
        $row.find('.pdf-id').val('');
        $row.find('.pdf-name').text('未選択');
      });

      $list.on('click', '.remove-row', function(){
        $(this).closest('.jtoc-row').remove();
      });
    })(jQuery);
    </script>
    <?php
  }, 'journal', 'normal', 'high');
});

// 保存
add_action('save_post_journal', function($post_id){
  if (!isset($_POST['journal_toc_nonce']) || !wp_verify_nonce($_POST['journal_toc_nonce'], 'save_journal_toc')) return;
  if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
  if (!current_user_can('edit_post', $post_id)) return;

  $input = isset($_POST['journal_toc']) && is_array($_POST['journal_toc']) ? $_POST['journal_toc'] : [];
  $clean = [];
  foreach ($input as $row){
    $title = isset($row['title']) ? sanitize_textarea_field($row['title']) : '';
    $aid   = isset($row['att_id']) ? absint($row['att_id']) : 0;
    $pages = isset($row['pages']) ? sanitize_text_field($row['pages']) : '';
    if (!$aid && $title==='') continue;
    if ($aid)  $clean[] = ['title'=>$title, 'att_id'=>$aid, 'pages'=>$pages];
  }
  if (!empty($clean)) update_post_meta($post_id, '_journal_toc', $clean);
  else delete_post_meta($post_id, '_journal_toc');
});



// journal: "ショートコードを有効化" チェック
add_action('init', function () {
  register_post_meta('journal', '_journal_enable_sc', [
    'type' => 'boolean',
    'single' => true,
    'show_in_rest' => true,
    'auth_callback' => fn() => current_user_can('edit_posts'),
    'sanitize_callback' => fn($v) => (bool)$v,
  ]);
});

add_action('add_meta_boxes', function () {
  add_meta_box('journal_sc_toggle', '本文のショートコード', function ($post) {
    wp_nonce_field('save_journal_sc', 'journal_sc_nonce');
    $on = (bool) get_post_meta($post->ID, '_journal_enable_sc', true);
    echo '<label><input type="checkbox" name="_journal_enable_sc" value="1" '.checked($on, true, false).'> この投稿でショートコードを有効化する</label>';
  }, 'journal', 'side', 'default');
});

add_action('save_post_journal', function ($post_id) {
  if (!isset($_POST['journal_sc_nonce']) || !wp_verify_nonce($_POST['journal_sc_nonce'], 'save_journal_sc')) return;
  if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
  if (!current_user_can('edit_post', $post_id)) return;
  update_post_meta($post_id, '_journal_enable_sc', isset($_POST['_journal_enable_sc']) ? 1 : 0);
});




/**
 * journal シングルで ?download=zip を受けたら、
 * _journal_toc の PDF を ZIP にまとめて配布。
 * 日本語ファイル名を保持しつつ、危険文字だけ除去/置換して重複も回避。
 */
add_filter('query_vars', function ($vars) {
  $vars[] = 'download';
  return $vars;
});

add_action('template_redirect', function () {
  if (!is_singular('journal')) return;
  if (get_query_var('download') !== 'zip') return;

  // 任意：会員限定
  if (function_exists('is_user_logged_in') && !is_user_logged_in()) {
    wp_redirect(home_url('/login/')); exit;
  }

  if (!class_exists('ZipArchive')) wp_die('サーバーのPHPで zip拡張が有効になっていません。', 500);

  global $post;
  $post_id = $post->ID;
  $toc = get_post_meta($post_id, '_journal_toc', true);
  if (!is_array($toc) || empty($toc)) wp_die('ダウンロードできるPDFが登録されていません。', 404);

  // ▼ 便利関数：ZIP用に“安全だが人間に読める”ファイル名を作る（日本語保持）
  $make_name = function (int $index, string $title = '', string $pages = '') : string {
    $base = trim($title);
    if ($base === '') $base = '無題';
    if ($pages !== '') $base .= '（' . $pages . '）';

    // OS/ZIPでNGな文字を安全置換
    $base = str_replace(
      ['\\','/',':','*','?','"','<','>','|'],
      '・', // 全て「・」に置換（お好みで別の記号でもOK）
      $base
    );
    // 制御文字・不可視文字を除去
    $base = preg_replace('/[\x00-\x1F\x7F]/u', '', $base);
    // 末尾のドット/スペースはWindowsで不可
    $base = rtrim($base, " .");

    // とても長い名前は UTF-8 バイト長で安全にカット（例: 120バイト）
    $max = 120;
    if (strlen($base) > $max) {
      $base = mb_strcut($base, 0, $max, 'UTF-8');
      $base = rtrim($base, " .");
    }

    return sprintf('%02d_%s.pdf', $index, $base);
  };

  // ▼ オフロード環境対応：ローカルに無い場合はURLから一時DL
  if (!function_exists('download_url')) {
    require_once ABSPATH . 'wp-admin/includes/file.php';
  }

  $entries   = []; // [ ['path'=>..., 'name'=>..., 'tmp'=>true/false], ... ]
  $name_set  = []; // 重複名回避用
  $i = 1;

  foreach ($toc as $row) {
    $aid = isset($row['att_id']) ? absint($row['att_id']) : 0;
    if (!$aid) continue;

    // 1) 実ファイルパスを取得
    $path    = get_attached_file($aid);
    $cleanup = false;

    if (!$path || !file_exists($path) || !is_readable($path)) {
      // ローカルに無ければURLから一時DL（S3等のオフロード対策）
      $url = wp_get_attachment_url($aid);
      if ($url) {
        $tmp = download_url($url);
        if (!is_wp_error($tmp) && file_exists($tmp)) {
          $path    = $tmp;
          $cleanup = true; // ZIP後に削除
        }
      }
    }
    if (!$path || !file_exists($path) || !is_readable($path)) continue;

    // 2) 見やすいファイル名を生成（日本語保持）
    $title = isset($row['title']) ? (string)$row['title'] : '';
    $pages = isset($row['pages']) ? (string)$row['pages'] : '';
    if ($title === '') $title = get_the_title($aid) ?: '';

    $name = $make_name($i, $title, $pages);

    // 3) 重複名があれば " (2)" などを付けてユニーク化
    $base = preg_replace('/\.pdf$/i', '', $name);
    $ext  = '.pdf';
    $n    = 2;
    while (isset($name_set[$name])) {
      $name = $base . ' (' . $n . ')' . $ext;
      $n++;
    }
    $name_set[$name] = true;

    $entries[] = ['path' => $path, 'name' => $name, 'tmp' => $cleanup];
    $i++;
  }

  if (empty($entries)) wp_die('有効なPDFファイルが見つかりませんでした。', 404);

  // ▼ ZIP作成
  @set_time_limit(0);
  ignore_user_abort(true);
  $tmpzip = function_exists('wp_tempnam') ? wp_tempnam('journal_zip') : tempnam(sys_get_temp_dir(), 'journal_zip_');
  if (!$tmpzip) wp_die('一時ファイルを作成できませんでした。', 500);

  $zip = new ZipArchive();
  if ($zip->open($tmpzip, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== true) {
    @unlink($tmpzip);
    wp_die('ZIPの作成に失敗しました。', 500);
  }

  foreach ($entries as $e) {
    // 日本語名をそのまま格納（UTF-8）。多くの解凍ソフトで正しく表示されます。
    $zip->addFile($e['path'], $e['name']);
  }
  $zip->close();

  // ▼ 応答（ZIPファイル名も人間が読める形に）
  $slug = get_post_field('post_name', $post_id) ?: 'journal';
  $title_for_zip = get_the_title($post_id) ?: $slug;
  $zipname = sanitize_file_name($title_for_zip) ?: $slug; // ここはHTTPヘッダ用なのでASCII寄りに
  $download_name = $zipname . '-PDF一括.zip';

  nocache_headers();
  header('Content-Type: application/zip');
  // UTF-8対応の Content-Disposition（各ブラウザ向け）
  header('Content-Disposition: attachment; filename="' . rawurlencode($download_name) . '"; filename*=UTF-8\'\'' . rawurlencode($download_name));
  header('Content-Length: ' . filesize($tmpzip));
  while (ob_get_level()) { ob_end_clean(); }
  readfile($tmpzip);

  // 後片付け
  @unlink($tmpzip);
  foreach ($entries as $e) {
    if (!empty($e['tmp'])) @unlink($e['path']);
  }
  exit;
});








?>