/** * ------------------------------------------------------------ * 注意: * ・以下を、現在有効なテーマ(子テーマ推奨)の functions.php の「末尾」に貼り付けてください。 * ・このコードが無くても route.php の分岐A・B・D は正常動作します(分岐Cだけが働きません)。 * * 動作: * ・管理画面にアクセス(ログイン済みで管理画面を表示)すると、判定用cookieを付与する。 * ・そのcookieを持つブラウザは、route.php 側で「許可IPと同等」= サイト通常表示になる。 * ・cookieは「セッションcookie」なので、ブラウザを閉じると自動的に消える。 * ・管理画面からログアウトしたときも削除する。 * * ※ PHP 7.3 以上が必要です(setcookie の配列オプションを使用)。 * ------------------------------------------------------------ */ // ★ zzzzz/route.php の設定($admin_cookie_name / $admin_cookie_secret)と必ず同じ値にすること ★ if (!defined('ADMIN_ACCESS_COOKIE_NAME')) define('ADMIN_ACCESS_COOKIE_NAME', 'bloom_admin'); if (!defined('ADMIN_ACCESS_COOKIE_SECRET')) define('ADMIN_ACCESS_COOKIE_SECRET', 'CHANGE_THIS_SECRET_12345'); // ---- 管理画面にアクセスしたら(ログイン済みのみ)セッションcookieを付与 ---- if (!function_exists('bloom_set_admin_cookie')) { function bloom_set_admin_cookie() { if (!is_user_logged_in()) { return; // ログインしていない訪問者には付与しない(自己付与による不正防止) } // すでに正しい値で付与済みなら再送しない if (isset($_COOKIE[ADMIN_ACCESS_COOKIE_NAME]) && hash_equals(ADMIN_ACCESS_COOKIE_SECRET, (string) $_COOKIE[ADMIN_ACCESS_COOKIE_NAME])) { return; } setcookie(ADMIN_ACCESS_COOKIE_NAME, ADMIN_ACCESS_COOKIE_SECRET, [ 'expires' => 0, // 0 = セッションcookie(ブラウザを閉じると消える) 'path' => '/', // サイト全体で有効 'secure' => is_ssl(), // httpsのときだけ送信 'httponly' => true, // JavaScriptから読めない(安全) 'samesite' => 'Lax', ]); // 同一リクエスト内でもすぐ有効化しておく $_COOKIE[ADMIN_ACCESS_COOKIE_NAME] = ADMIN_ACCESS_COOKIE_SECRET; } // admin_init はログイン済みで管理画面を表示したときに実行される add_action('admin_init', 'bloom_set_admin_cookie'); } // ---- ログアウト時に削除 ---- if (!function_exists('bloom_clear_admin_cookie')) { function bloom_clear_admin_cookie() { setcookie(ADMIN_ACCESS_COOKIE_NAME, '', [ 'expires' => time() - 3600, // 過去時刻で失効させる 'path' => '/', 'secure' => is_ssl(), 'httponly' => true, 'samesite' => 'Lax', ]); unset($_COOKIE[ADMIN_ACCESS_COOKIE_NAME]); } add_action('wp_logout', 'bloom_clear_admin_cookie'); } /** * ------------------------------------------------------------ * アクセス制御(IP/リファラ判定によるリダイレクト・404)は * mu-plugin(wp-content/mu-plugins/ecpid-early-gate.php)へ移設済み。 * このファイルには「サイト表示に必要な機能」だけを残しています。 * * - ecpid_get_server_base() … SQLite等の外部ファイルパス取得(下記機能で使用) * - メタディスクリプション出力 * - 関連商品の非表示 * - [rep] ショートコード(共有SQLiteから値を読み込み) * - タイトル / パンくずでのショートコード実行 * - WooCommerce 価格の SQLite 上書き * ------------------------------------------------------------ */ if (!defined('ABSPATH')) { exit; } /** * 外部ファイル用の「サーバーのユーザー領域」を取得する。 * ABSPATH 例: /home/wfucohup/ec-pid.com/ → /home/wfucohup を返す * ※ mu-plugin 側でも同名関数を定義しているため function_exists でガード * (mu-plugin が無くても、この functions.php 単体で動作します)。 */ if (!function_exists('ecpid_get_server_base')) { function ecpid_get_server_base() { if (defined('ABSPATH') && preg_match('#^(/home/[^/]+)/#', ABSPATH, $m)) { return $m[1]; } } } /* ============================================================ * メタディスクリプション出力(商品ページのカスタムフィールド) * ============================================================ */ function add_custom_description() { if ( function_exists( 'is_product' ) && is_product() ) { global $post; if ( $post instanceof WP_Post ) { $description = get_post_meta( $post->ID, 'prd_description', true ); if ( $description ) { echo ''; } } } } add_action('wp_head', 'add_custom_description'); /* ============================================================ * 関連商品を非表示 * ============================================================ */ remove_action( 'woocommerce_after_single_product_summary', 'woocommerce_output_related_products', 20 ); /* ============================================================ * [rep] ショートコード:共有SQLiteファイルから値を読み込む(本番用:エラー非表示版) * ============================================================ */ add_shortcode('rep', function($atts) { $key = isset($atts['k']) ? $atts['k'] : ''; $params = explode('_', $key); if (count($params) !== 3) return ''; list($site_name, $pid, $col_name) = $params; $allowed_cols = ['unit', 'lot']; if (!in_array($col_name, $allowed_cols)) return ''; $db_path = ecpid_get_server_base() . '/zzzzz/product_price.sqlite'; if (!file_exists($db_path)) return ''; try { $db = new PDO("sqlite:$db_path"); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $sql = "SELECT {$col_name} FROM common_data WHERE site = :site AND pid = :pid LIMIT 1"; $stmt = $db->prepare($sql); $stmt->execute([':site' => $site_name, ':pid' => $pid]); $result = $stmt->fetchColumn(); if ($result !== false) { // 数値であればカンマ区切り(number_format)にする if (is_numeric($result)) { $result = number_format((float)$result); } return esc_html($result); } else { return ''; } } catch (PDOException $e) { return ''; } }); /* ============================================================ * タイトル / パンくずでショートコードを実行する * ============================================================ */ // タグ内のショートコードを実行する(WordPress標準) add_filter( 'document_title_parts', function( $title_parts ) { if ( isset( $title_parts['title'] ) ) { $title_parts['title'] = do_shortcode( $title_parts['title'] ); } return $title_parts; }, 999 ); // h1タグ(ページタイトル)でショートコードを実行する add_filter( 'single_post_title', 'do_shortcode', 999 ); add_filter( 'woocommerce_page_title', 'do_shortcode', 999 ); add_filter( 'single_term_title', 'do_shortcode', 999 ); // カテゴリページ等のh1用 add_filter( 'the_title', function( $title, $id = null ) { // 管理画面内では実行しない安全対策 if ( ! is_admin() ) { return do_shortcode( $title ); } return $title; }, 999, 2 ); // WooCommerce標準のパンくずリストでショートコードを実行する add_filter( 'woocommerce_get_breadcrumb', function( $crumbs, $breadcrumb ) { if ( ! empty( $crumbs ) && is_array( $crumbs ) ) { foreach ( $crumbs as $key => $crumb ) { $crumbs[$key][0] = do_shortcode( $crumb[0] ); } } return $crumbs; }, 999, 2 ); /* ============================================================ * カスタムフィールドの値を使って WooCommerce の価格を SQLite から上書きする * ============================================================ */ add_filter( 'woocommerce_product_get_price', 'override_price_with_sqlite', 10, 2 ); add_filter( 'woocommerce_product_get_regular_price', 'override_price_with_sqlite', 10, 2 ); function override_price_with_sqlite( $price, $product ) { // 商品に設定されたカスタムフィールド「shared_price_key」の値を取得 $key = get_post_meta( $product->get_id(), 'shared_price_key', true ); // キーが無ければ元の価格をそのまま使う if ( empty( $key ) ) { return $price; } // [rep k="navi_1_unit"] のようにカッコ付きで入力された場合、中身だけ抽出 if ( preg_match('/k="([^"]+)"/', $key, $matches) ) { $key = $matches[1]; } $params = explode('_', $key); if (count($params) !== 3) return $price; list($site_name, $pid, $col_name) = $params; $allowed_cols = ['unit', 'lot']; if (!in_array($col_name, $allowed_cols)) return $price; $db_path = ecpid_get_server_base() . '/zzzzz/product_price.sqlite'; if (!file_exists($db_path)) return $price; try { $db = new PDO("sqlite:$db_path"); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $sql = "SELECT {$col_name} FROM common_data WHERE site = :site AND pid = :pid LIMIT 1"; $stmt = $db->prepare($sql); $stmt->execute([':site' => $site_name, ':pid' => $pid]); $result = $stmt->fetchColumn(); // 数値が取得できたら価格として上書き(※カート計算のためカンマは付けない) if ($result !== false && is_numeric($result)) { return $result; } } catch (PDOException $e) { return $price; } return $price; } <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=euc-jp"/> <title>±¡Ä¹¤Î¤´¾Ò²ð | ¤Ï¤Þ¤°¤ÁÆâ²Ê¥¯¥ê¥Ë¥Ã¥¯

¤Ï¤Þ¤°¤ÁÆâ²Ê¥¯¥ê¥Ë¥Ã¥¯

Ê¿Æü
¸áÁ° / 9¡§00¡Á12¡§00¡¡¸á¸å / 14¡§00¡Á18¡§00
ÅÚÍËÆü
¸áÁ° / 9¡§00¡Á12¡§00¤Î¤ß
Æü¡¦½Ë
µÙ¤ß
06-1234-5678 ¢©583-0027 ÂçºåÉÜÆ£°æ»û»Ô²¬2ÃúÌÜ8-46 ¥¢¥³¡¼¥ë¡¦¥¢¥ó2F

¥Ú¡¼¥¸ÀèÆ¬¤ØÌá¤ë