# [メタ情報] # 識別子: functionsphp全文_exe # 補足: env終了 # [/メタ情報] 要約: このWordPress子テーマの`functions.php`は、共通設定の読み込みを起点に、多岐にわたるカスタム機能を提供する。具体的には、固定ページにおけるCocoonテーマのモバイルフッター非表示化、`[dynamic_external_html]`による外部テキスト埋め込み、`[videoembed]`による動画埋め込み(JSON設定ベース)、`[pub_txt_list]`による安全なTXTファイルリスト表示・配信、管理者向けCocoon PV表示ON/OFFトグル機能がある。さらに、特定文字列`[ID: ]`の`[ID-]`へのJavaScript変換、定義済み定数に基づくQ&Aバナーの動的生成ショートコード`[XXXXXX_notebook_banner]`も実装されている。これらの機能は、サイト管理とコンテンツ表示の柔軟性・安全性を高めることを目的としている。 themes/cocoon-child-master/functions.php ``` ''), $atts); $url = $attributes['url']; if (empty($url)) return '◆◆◆'; // URLがルート相対パス(例: /_secure/...)の場合、wp_remote_getのためにURLを動的補完 if (strpos($url, '/') === 0) { $url = home_url($url); } $response = wp_remote_get($url); if (is_wp_error($response)) return 'テキストの読み込みに失敗しました。'; return wp_remote_retrieve_body($response); } function display_dynamic_external_html($atts) { return fetch_dynamic_external_html_content($atts); } add_shortcode('dynamic_external_html', 'display_dynamic_external_html'); /* ========================================================================= * 2) 動画埋め込み: [videoembed videoid="..."] * =======================================================================*/ function videoembed_shortcode($atts) { $atts = shortcode_atts(array('videoid' => ''), $atts, 'videoembed'); $video_id = $atts['videoid']; if (empty($video_id)) return '
動画はまだ準備中です。
'; // 動画IDの読み替え(すり替え) if (function_exists('get_alt_video_id')) { $video_id = get_alt_video_id($video_id); } // JSONファイルの読み込み(ABSPATH基準で高速かつWAFブロックを安全回避) $json_path = ABSPATH . '../_secure/wp_json/videoembed.json'; if (!file_exists($json_path)) { $json_path = $_SERVER['DOCUMENT_ROOT'] . '/_secure/wp_json/videoembed.json'; } if (file_exists($json_path)) { $json_data = @file_get_contents($json_path); if ($json_data !== false) { $embed_array = json_decode($json_data, true); if (is_array($embed_array)) { foreach ($embed_array as $entry) { if (isset($entry['videoid']) && (string)$entry['videoid'] === (string)$video_id) { return do_shortcode($entry['embedCode']); } } } } } return '動画はまだ準備中です。
'; } add_shortcode('videoembed', 'videoembed_shortcode'); /* ========================================================================= * 3) 公開用TXTリスト: [pub_txt_list] * =======================================================================*/ add_shortcode('pub_txt_list', function($atts){ $base_dir = WP_CONTENT_DIR . '/pmedia/scripts_pub'; $allowed_exts = ['txt']; $exclude_files = ['key_patterns.txt']; $exclude_dirs = ['@eaDir']; $uid = 'pub-txt-' . (function_exists('wp_generate_uuid4') ? wp_generate_uuid4() : uniqid()); if (!is_dir($base_dir)) return '一覧ディレクトリが存在しません。
'; // ページURL(この固定ページ自身)を動的取得して、パンくずやソート遷移を同じページ内に固定 $page_url = get_permalink(); if (!$page_url) $page_url = home_url(add_query_arg([], '/')); // === 現在のディレクトリパスの解析 === $rel_dir = ''; if (isset($_GET['pubtxt_dir']) && is_string($_GET['pubtxt_dir'])) { $rel_dir = trim(str_replace('\\', '/', $_GET['pubtxt_dir']), '/'); } if ($rel_dir === '.' || strpos($rel_dir, '..') !== false || strpos($rel_dir, "\0") !== false) $rel_dir = ''; $current_dir = $base_dir . ($rel_dir ? '/' . $rel_dir : ''); if (!is_dir($current_dir)) { $rel_dir = ''; $current_dir = $base_dir; } // === ソートパラメータの処理 === $validSort = ['name', 'mtime', 'size']; $sort = (isset($_GET['sort']) && in_array($_GET['sort'], $validSort, true)) ? $_GET['sort'] : 'mtime'; $order = (isset($_GET['order']) && in_array(strtolower($_GET['order']), ['asc', 'desc'], true)) ? strtolower($_GET['order']) : 'desc'; $initial_sort_chain = [ ['key' => 'mtime', 'dir' => 'desc'], ['key' => 'name', 'dir' => 'asc'], ['key' => 'size', 'dir' => 'asc'], ]; // 見出しクリック時の次ソート順の決定 $nextOrder = function($key) use ($sort, $order) { if ($key !== $sort) { return ($key === 'mtime') ? 'desc' : 'asc'; } return ($order === 'asc') ? 'desc' : 'asc'; }; // URL組み立て用のクロージャ $url_with = function(array $add) use ($page_url, $rel_dir, $sort, $order) { $args = ['pubtxt_dir' => $rel_dir]; if ($sort) $args['sort'] = $sort; if ($order) $args['order'] = $order; foreach ($add as $k => $v) { if ($v === null) unset($args[$k]); else $args[$k] = $v; } return add_query_arg($args, $page_url); }; // 日本時間形式の日付フォーマッタ $fmt = function($f, $ts) { if (function_exists('wp_date')) { $s = wp_date($f, $ts); if($s) return $s; } return date_i18n($f, $ts); }; // === 1階層のみを走査 === $items = []; foreach (scandir($current_dir) as $name) { if ($name === '.' || $name === '..') continue; if ($name[0] === '.' || in_array($name, $exclude_dirs, true)) continue; // 隠しディレクトリ・@eaDir等の除外 if (in_array($name, $exclude_files, true)) continue; $full = $current_dir . '/' . $name; if (!is_readable($full)) continue; $rel = ltrim($rel_dir . '/' . $name, '/'); $mtime = @filemtime($full) ?: 0; if (is_dir($full)) { $items[] = [ 'type' => 'dir', 'name' => $name, 'rel' => $rel, 'mtime' => $mtime, 'size' => 0, 'href' => $url_with(['pubtxt_dir' => $rel, 'sort' => null, 'order' => null]), // 階層移動時は初期順で開始 ]; } elseif (is_file($full)) { $ext = strtolower(pathinfo($name, PATHINFO_EXTENSION)); if ($ext !== 'txt') continue; // 公開用の安全基準として .txt のみに厳格制限 $size = @filesize($full) ?: 0; $items[] = [ 'type' => 'file', 'name' => $name, 'rel' => $rel, 'mtime' => $mtime, 'size' => $size, 'view' => add_query_arg(['pubtxt' => $rel], $page_url), 'dl' => add_query_arg(['pubtxt' => $rel, 'dl' => '1'], $page_url) ]; } } if (!$items) return '対象ファイルがありません。
'; // === ソート実装(主キー: $sort/$order、従キー: mtime desc → name asc → size asc の多重チェーン) === usort($items, function($a, $b) use ($sort, $order, $initial_sort_chain) { $compare = function($x, $y, $key, $dir) { $vx = $x[$key] ?? null; $vy = $y[$key] ?? null; $cmp = ($key === 'name') ? strcasecmp((string)$vx, (string)$vy) : ($vx <=> $vy); return ($dir === 'asc') ? $cmp : -$cmp; }; $c = $compare($a, $b, $sort, $order); if ($c !== 0) return $c; foreach ($initial_sort_chain as $chain) { $k = $chain['key']; $d = $chain['dir']; $c = $compare($a, $b, $k, $d); if ($c !== 0) return $c; } return 0; }); $latest = max(array_column($items, 'mtime')); // 見出しクリック用のリンク生成 $th_link = function($key, $label) use ($page_url, $rel_dir, $nextOrder) { $url = add_query_arg(['pubtxt_dir' => $rel_dir, 'sort' => $key, 'order' => $nextOrder($key)], $page_url); return '' . $label . ''; }; // パンくずの組み立て $crumbs = [['name' => 'root', 'dir' => '']]; if ($rel_dir) { $parts = explode('/', $rel_dir); $accum = ''; foreach ($parts as $p) { $accum = ltrim($accum . '/' . $p, '/'); $crumbs[] = ['name' => $p, 'dir' => $accum]; } } $crumb_html = []; foreach ($crumbs as $idx => $cr) { if ($idx === count($crumbs) - 1) { $crumb_html[] = esc_html($cr['name']); } else { $url = add_query_arg(['pubtxt_dir' => $cr['dir'], 'sort' => null, 'order' => null], $page_url); $crumb_html[] = '' . esc_html($cr['name']) . ''; } } ob_start(); ?>| 操作 | |||
|---|---|---|---|
| .. | 戻る | ||
| 📁 📄 |