差分

このページの2つのバージョン間の差分を表示します。

この比較画面へのリンク

次のリビジョン
前のリビジョン
48th_8j1ham_rs [2026/08/25 20:49] – 作成 Tana JH1HST48th_8j1ham_rs [2026/08/27 03:54] (現在) Tana JH1HST
行 1: 行 1:
 +~~NOCACHE~~
 +
 ====== 8J1HAM 会場公開運用 当選確認 ====== ====== 8J1HAM 会場公開運用 当選確認 ======
 +
 +第48回アマチュア無線フェスティバル ハムフェア2026
  
 特別記念局 **8J1HAM 会場公開運用**へ多数のお申し込みをいただき、ありがとうございました。 特別記念局 **8J1HAM 会場公開運用**へ多数のお申し込みをいただき、ありがとうございました。
  
-下の入力欄に、**お申し込み時に登録したコールサインまたはメールアドレス**を入力して、選結果をご確認ください。+下の入力欄に、**お申し込み時に登録したコールサインまたはメールアドレス**を入力して、選結果をご確認ください。
  
 体験運用でお申し込みの方など、コールサインを登録していない場合は、**お申し込み時のメールアドレス**を入力してください。 体験運用でお申し込みの方など、コールサインを登録していない場合は、**お申し込み時のメールアドレス**を入力してください。
行 19: 行 23:
         return '8月29日(土)';         return '8月29日(土)';
     }     }
 +
     if ($date === '2026-08-30') {     if ($date === '2026-08-30') {
         return '8月30日(日)';         return '8月30日(日)';
     }     }
 +
     return $date;     return $date;
 } }
行 27: 行 33:
 echo ' echo '
 <style> <style>
-.hf-result-wrap {+ 
 +#hf-result-wrap { 
 +    width: 100%;
     max-width: 760px;     max-width: 760px;
-    margin: 24px auto;+    margin: 20px 0; 
 +    padding: 0 0 0 16px; 
 +    box-sizing: border-box; 
 +    clear: both;
 } }
  
-.hf-search-box {+#hf-search-panel { 
 +    width: 100%; 
 +    box-sizing: border-box;
     background: #f7f8fa;     background: #f7f8fa;
     border: 1px solid #d8dce2;     border: 1px solid #d8dce2;
     border-radius: 10px;     border-radius: 10px;
-    padding: 20px;+    padding: 20px 20px 20px 24px;
     margin: 20px 0;     margin: 20px 0;
 } }
  
-.hf-search-label +#hf-search-form 
-    display: block; +    display: block !important
-    font-weightbold+    width100% !important
-    margin-bottom8px;+    margin: 0 !important; 
 +    padding: 0 !important; 
 +    border: 0 !important; 
 +    background: transparent !important; 
 +    box-shadow: none !important; 
 +    border-radius: 0 !important; 
 +    positionstatic !important;
 } }
  
-.hf-search-row +#hf-search-form::before, 
-    display: flex+#hf-search-form::after 
-    gap: 8px; +    display: none !important
-    flex-wrapwrap;+    contentnone !important;
 } }
  
-.hf-search-input +#hf-search-form label 
-    flex1 1 360px+    displayblock !important
-    min-width220px+    margin0 0 8px 6px !important
-    padding: 11px 12px+    padding: 0 !important
-    font-size16px; +    font-weightbold !important;
-    border: 1px solid #aaa; +
-    border-radius: 6px;+
 } }
  
-.hf-search-button +#hf-search-form input[type="text"
-    padding11px 20px+    displayblock !important
-    font-size: 16px+    width: calc(100% 12px) !important
-    font-weightbold+    max-widthcalc(100% - 12px) !important
-    cursorpointer+    heightauto !important
-    border: 0; +    box-sizing: border-box !important; 
-    border-radius: 6px; +    margin: 0 6px 12px 6px !important; 
-    color: #fff; +    padding: 11px 12px !important; 
-    background#1769aa;+    border: 1px solid #999 !important
 +    border-radius: 6px !important
 +    background: #fff !important
 +    font-size16px !important;
 } }
  
-.hf-search-button:hover +#hf-search-form button { 
-    background: #0d568e;+    display: inline-block !important; 
 +    width: auto !important; 
 +    margin: 0 0 0 6px !important; 
 +    padding: 11px 20px !important; 
 +    border: 0 !important; 
 +    border-radius: 6px !important; 
 +    background: #1769aa !important; 
 +    color: #fff !important; 
 +    font-size: 16px !important; 
 +    font-weight: bold !important; 
 +    cursor: pointer !important;
 } }
  
-.hf-small +#hf-search-form button:hover { 
-    color: #666; +    background: #0d568e !important; 
-    font-size: 0.92em+
-    margin-top: 10px;+ 
 +#hf-search-help { 
 +    display: block !important; 
 +    margin: 10px 6px 0 6px !important; 
 +    padding: 0 !important; 
 +    color: #666 !important
 +    font-size: 0.92em !important;
 } }
  
 .hf-winner { .hf-winner {
 +    width: 100%;
 +    box-sizing: border-box;
     margin: 24px 0;     margin: 24px 0;
     padding: 22px;     padding: 22px;
行 133: 行 171:
  
 .hf-not-selected { .hf-not-selected {
 +    width: 100%;
 +    box-sizing: border-box;
     margin: 24px 0;     margin: 24px 0;
     padding: 22px;     padding: 22px;
行 143: 行 183:
     color: #555;     color: #555;
     font-size: 1.15em;     font-size: 1.15em;
 +    font-weight: bold;
 +    margin-bottom: 12px;
 +}
 +
 +.hf-cancelled {
 +    width: 100%;
 +    box-sizing: border-box;
 +    margin: 24px 0;
 +    padding: 22px;
 +    background: #fff4e5;
 +    border: 2px solid #e0a24a;
 +    border-radius: 10px;
 +}
 +
 +.hf-cancelled-title {
 +    color: #b06000;
 +    font-size: 1.25em;
     font-weight: bold;     font-weight: bold;
     margin-bottom: 12px;     margin-bottom: 12px;
行 148: 行 205:
  
 .hf-not-found { .hf-not-found {
 +    width: 100%;
 +    box-sizing: border-box;
     margin: 24px 0;     margin: 24px 0;
-    padding: 18px;+    padding: 18px 18px 18px 24px;
     background: #fff8df;     background: #fff8df;
     border-left: 5px solid #d9a800;     border-left: 5px solid #d9a800;
行 155: 行 214:
  
 .hf-error { .hf-error {
 +    width: 100%;
 +    box-sizing: border-box;
     margin: 24px 0;     margin: 24px 0;
-    padding: 18px;+    padding: 18px 18px 18px 24px;
     background: #fff0f0;     background: #fff0f0;
     border-left: 5px solid #c62828;     border-left: 5px solid #c62828;
 } }
 +
 +@media screen and (max-width: 600px) {
 +
 +    #hf-result-wrap {
 +        padding-left: 8px;
 +    }
 +
 +    #hf-search-panel,
 +    .hf-winner,
 +    .hf-not-selected,
 +    .hf-cancelled {
 +        padding: 16px;
 +    }
 +
 +    #hf-search-form button {
 +        display: block !important;
 +        width: calc(100% - 12px) !important;
 +        margin: 0 6px !important;
 +    }
 +
 +    .hf-result-table {
 +        font-size: 0.95em;
 +    }
 +
 +    .hf-result-table th,
 +    .hf-result-table td {
 +        padding: 8px 5px;
 +    }
 +}
 +
 </style> </style>
  
-<div class="hf-result-wrap">+<div id="hf-result-wrap">
  
-<form method="post" class="hf-search-box"+    <div id="hf-search-panel">
-    <label class="hf-search-label" for="hf_lookup"> +
-        コールサイン または メールアドレス +
-    </label>+
  
-    <div class="hf-search-row"> +        <form method="post" id="hf-search-form">
-        <input +
-            type="text" +
-            id="hf_lookup" +
-            name="hf_lookup" +
-            class="hf-search-input" +
-            value="" +
-            autocomplete="off" +
-            required +
-        > +
-        <button type="submit" class="hf-search-button"> +
-            当選結果を確認する +
-        </button> +
-    </div>+
  
-    <div class="hf-small"> +            <label for="hf_lookup"> 
-        お申し込み時に登録した内容を入力してください。部分一致ではなく完全一致で確認します。 +                コールサイン または メールアドレス 
-    </div> +            </label> 
-</form>+ 
 +            <input 
 +                type="text" 
 +                id="hf_lookup" 
 +                name="hf_lookup" 
 +                autocomplete="off" 
 +                autocapitalize="none" 
 +                spellcheck="false" 
 +                maxlength="254" 
 +                pattern="[A-Za-z0-9@._%+/\-]+" 
 +                title="半角英数字と @ . _ % + - / のみ使用できます" 
 +                required 
 +            > 
 + 
 +            <button type="submit"> 
 +                当選結果を確認する 
 +            </button> 
 + 
 +            <div id="hf-search-help"> 
 +                お申し込み時に登録した内容を入力してください。部分一致ではなく完全一致で確認します。 
 +            </div> 
 + 
 +        </form
 + 
 +        <script> 
 +        document.addEventListener("DOMContentLoaded", function () { 
 + 
 +            var input = document.getElementById("hf_lookup"); 
 + 
 +            if (!input) { 
 +                return; 
 +            } 
 + 
 +            input.addEventListener("input", function () { 
 + 
 +                this.value = this.value.normalize("NFKC"); 
 + 
 +            }); 
 + 
 +        }); 
 +        </script>
 '; ';
  
 if ($_SERVER['REQUEST_METHOD'] === 'POST') { if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  
-    $input = isset($_POST['hf_lookup']) ? trim((string)$_POST['hf_lookup']) : '';+    $input = isset($_POST['hf_lookup']) 
 +        ? trim((string)$_POST['hf_lookup']) 
 +        : ''
 + 
 +    if (function_exists('mb_convert_kana')) { 
 +        $input = mb_convert_kana($input, 'as', 'UTF-8'); 
 +    } 
 + 
 +    $input = strtr( 
 +        $input, 
 +        array( 
 +            '@' => '@', 
 +            '.' => '.', 
 +            '_' => '_', 
 +            '%' => '%', 
 +            '+' => '+', 
 +            '-' => '-', 
 +            'ー' => '-', 
 +            '/' => '/' 
 +        ) 
 +    );
  
     if ($input === '') {     if ($input === '') {
 +
         echo '         echo '
         <div class="hf-not-found">         <div class="hf-not-found">
行 200: 行 336:
         </div>         </div>
         ';         ';
 +
 +    } elseif (preg_match('/[^A-Za-z0-9@._%+\/-]/', $input) === 1) {
 +
 +        echo '
 +        <div class="hf-not-found">
 +            <strong>使用できない文字が含まれています。</strong><br>
 +            コールサインまたはメールアドレスを半角英数字で入力してください。
 +        </div>
 +        ';
 +
     } elseif (!is_file($db_file)) {     } elseif (!is_file($db_file)) {
 +
         echo '         echo '
         <div class="hf-error">         <div class="hf-error">
-            現在、選結果データを読み込むことができません。+            現在、選結果データを読み込むことができません。
             しばらくしてから再度お試しください。             しばらくしてから再度お試しください。
         </div>         </div>
         ';         ';
 +
     } else {     } else {
  
         try {         try {
 +
             $pdo = new PDO(             $pdo = new PDO(
                 'sqlite:' . $db_file,                 'sqlite:' . $db_file,
行 220: 行 369:
             );             );
  
-            /* 
-             * コールサインは大文字小文字を区別せず、 
-             * メールアドレスも大文字小文字を区別せず完全一致。 
-             */ 
             $callsign_norm = strtoupper($input);             $callsign_norm = strtoupper($input);
             $email_norm    = strtolower($input);             $email_norm    = strtolower($input);
  
-            /* 
-             * まず「申込そのものが存在するか」を確認。 
-             * 
-             * 同一メールアドレスで複数申込が存在する場合もあるため、 
-             * 1件に限定せず applicant_id を取得する。 
-             */ 
             $stmt = $pdo->prepare(             $stmt = $pdo->prepare(
                 'SELECT applicant_id, callsign, email                 'SELECT applicant_id, callsign, email
行 240: 行 379:
             );             );
  
-            $stmt->execute(array( +            $stmt->execute( 
-                ':callsign' => $callsign_norm, +                array( 
-                ':email'    => $email_norm +                    ':callsign' => $callsign_norm, 
-            ));+                    ':email'    => $email_norm 
 +                ) 
 +            );
  
             $applicants = $stmt->fetchAll();             $applicants = $stmt->fetchAll();
行 259: 行 400:
  
                 $ids = array();                 $ids = array();
 +
                 foreach ($applicants as $applicant) {                 foreach ($applicants as $applicant) {
                     $ids[] = $applicant['applicant_id'];                     $ids[] = $applicant['applicant_id'];
                 }                 }
  
-                /* +                $placeholders = implode( 
-                 * 一致した申込IDの中に当選結果があるか確認。 +                    ',', 
-                 * 重複申込があった場合でも、当選している申込を拾える。 +                    array_fill(0, count($ids), '?') 
-                 */ +                );
-                $placeholders = implode(',', array_fill(0, count($ids), '?'));+
  
                 $stmt = $pdo->prepare(                 $stmt = $pdo->prepare(
-                    'SELECT applicant_id, +                    'SELECT 
-                            callsign, +                        applicant_id, 
-                            email, +                        callsign, 
-                            date, +                        email, 
-                            start_time, +                        date, 
-                            end_time, +                        start_time, 
-                            band, +                        end_time, 
-                            operation_type, +                        band, 
-                            slot_type +                        operation_type, 
-                       FROM results +                        slot_type
-                      WHERE applicant_id IN (' . $placeholders . ') +                        status 
-                      ORDER BY date, start_time'+                     FROM results 
 +                     WHERE applicant_id IN (' . $placeholders . ') 
 +                     ORDER BY date, start_time'
                 );                 );
  
                 $stmt->execute($ids);                 $stmt->execute($ids);
 +
                 $results = $stmt->fetchAll();                 $results = $stmt->fetchAll();
  
行 290: 行 434:
  
                     foreach ($results as $result) {                     foreach ($results as $result) {
 +
 +                        /*
 +                         * キャンセル済み
 +                         */
 +                        if (
 +                            isset($result['status'])
 +                            && $result['status'] === 'cancelled'
 +                        ) {
 +
 +                            $date_text = hf_date_jp($result['date']);
 +
 +                            $time_text =
 +                                $result['start_time']
 +                                . '~'
 +                                . $result['end_time'];
 +
 +                            echo '
 +                            <div class="hf-cancelled">
 +
 +                                <div class="hf-cancelled-title">
 +                                    この運用枠はキャンセル済みです。
 +                                </div>
 +
 +                                <table class="hf-result-table">
 +
 +                                    <tr>
 +                                        <th>日付</th>
 +                                        <th>時間</th>
 +                                        <th>バンド</th>
 +                                        <th>状態</th>
 +                                    </tr>
 +
 +                                    <tr>
 +
 +                                        <td>'
 +                                        . hf_h($date_text)
 +                                        . '</td>
 +
 +                                        <td>'
 +                                        . hf_h($time_text)
 +                                        . '</td>
 +
 +                                        <td>
 +                                            <strong>'
 +                                            . hf_h($result['band'])
 +                                            . '</strong>
 +                                        </td>
 +
 +                                        <td>
 +                                            <strong>キャンセル済み</strong>
 +                                        </td>
 +
 +                                    </tr>
 +
 +                                </table>
 +
 +                                <p>
 +                                    キャンセルとして受け付けています。
 +                                </p>
 +
 +                            </div>
 +                            ';
 +
 +                            continue;
 +                        }
  
                         $date_text = hf_date_jp($result['date']);                         $date_text = hf_date_jp($result['date']);
-                        $time_text = $result['start_time'] . '~' . $result['end_time'];+ 
 +                        $time_text = 
 +                            $result['start_time'] 
 +                            . '~' 
 +                            . $result['end_time'];
  
                         echo '                         echo '
行 298: 行 511:
  
                             <div class="hf-winner-title">                             <div class="hf-winner-title">
-                                おめでとうございます。選の結果、当選しました。+                                おめでとうございます。選の結果、当選しました。
                             </div>                             </div>
  
                             <table class="hf-result-table">                             <table class="hf-result-table">
 +
                                 <tr>                                 <tr>
                                     <th>日付</th>                                     <th>日付</th>
行 308: 行 522:
                                     <th>結果</th>                                     <th>結果</th>
                                 </tr>                                 </tr>
 +
                                 <tr>                                 <tr>
-                                    <td>' . hf_h($date_text) . '</td> + 
-                                    <td>' . hf_h($time_text) . '</td> +                                    <td>' 
-                                    <td><strong>' . hf_h($result['band']) . '</strong></td> +                                    . hf_h($date_text) 
-                                    <td class="hf-pass">当選</td>+                                    . '</td> 
 + 
 +                                    <td>' 
 +                                    . hf_h($time_text) 
 +                                    . '</td> 
 + 
 +                                    <td> 
 +                                        <strong>' 
 +                                        . hf_h($result['band']) 
 +                                        . '</strong> 
 +                                    </td> 
 + 
 +                                    <td class="hf-pass"> 
 +                                        当選 
 +                                    </td> 
                                 </tr>                                 </tr>
 +
                             </table>                             </table>
                         ';                         ';
  
                         if (!empty($result['callsign'])) {                         if (!empty($result['callsign'])) {
 +
                             echo '                             echo '
                             <p>                             <p>
                                 コールサイン:                                 コールサイン:
-                                <strong>' . hf_h($result['callsign']) . '</strong>+                                <strong>' 
 +                                . hf_h($result['callsign']) 
 +                                . '</strong>
                             </p>                             </p>
                             ';                             ';
 +
                         } else {                         } else {
-                            /* + 
-                             * 体験運用などコールサインがない場合は、 +                            $email = $result['email']; 
-                             * メールアドレスをそのまま再表示せず、 + 
-                             登録メールアドレスで確認された旨だけ表示。 +                            $parts = explode('@', $email, 2); 
-                             */+ 
 +                            if (count($parts) === 2) { 
 + 
 +                                $local  = $parts[0]; 
 +                                $domain = $parts[1]; 
 + 
 +                                if ($local !== '') { 
 +                                    $masked = 
 +                                        substr($local, 0, 1) 
 +                                        . '***@' 
 +                                        . $domain; 
 +                                } else { 
 +                                    $masked = '***@' . $domain; 
 +                                } 
 + 
 +                            } else { 
 + 
 +                                $masked = $email; 
 +                            } 
                             echo '                             echo '
                             <p>                             <p>
-                                お申し込み時のメールアドレスで確認しました。+                                登録メールアドレス: 
 +                                <strong>' 
 +                                . hf_h($masked) 
 +                                . '</strong>
                             </p>                             </p>
                             ';                             ';
行 338: 行 595:
  
                         if (                         if (
-                            $result['operation_type'] === '体験運用' ||+                            $result['operation_type'] === '体験運用' 
 +                            ||
                             $result['operation_type'] === '資格範囲外:体験運用'                             $result['operation_type'] === '資格範囲外:体験運用'
                         ) {                         ) {
 +
                             echo '                             echo '
                             <p>                             <p>
行 351: 行 610:
                         echo '                         echo '
                             <div class="hf-guide">                             <div class="hf-guide">
-                                <strong>当選された方は、当日までに必ず以下のガイドをご確認ください。</strong>+ 
 +                                <strong> 
 +                                    当選された方は、当日までに必ず以下のガイドをご確認ください。 
 +                                </strong> 
                                 <br><br>                                 <br><br>
-                                <a href="https://hamfair.jp/8J1ham_pub/guide/" target="_blank" rel="noopener">+ 
 +                                <a 
 +                                    href="https://hamfair.jp/8J1ham_pub/guide/" 
 +                                    target="_blank" 
 +                                    rel="noopener" 
 +                                >
                                     8J1HAM 会場公開運用 当選者向けガイド                                     8J1HAM 会場公開運用 当選者向けガイド
                                 </a>                                 </a>
 +
                             </div>                             </div>
  
行 368: 行 637:
  
                         <div class="hf-not-selected-title">                         <div class="hf-not-selected-title">
-                            厳正なる選の結果、今回は残念ながら運用枠をご用意することができませんでした。+                            厳正なる選の結果、今回は残念ながら運用枠をご用意することができませんでした。
                         </div>                         </div>
  
行 382: 行 651:
         } catch (Exception $e) {         } catch (Exception $e) {
  
-            /* 
-             * DBの内部エラー内容は公開画面には表示しない。 
-             */ 
             echo '             echo '
             <div class="hf-error">             <div class="hf-error">
-                選結果の確認中にエラーが発生しました。+                選結果の確認中にエラーが発生しました。
                 しばらくしてから再度お試しください。                 しばらくしてから再度お試しください。
             </div>             </div>
行 395: 行 661:
 } }
  
-echo '</div>';+echo ' 
 +</div> 
 +';
  
 </php> </php>
  • 48th_8j1ham_rs.1787658566.txt.gz
  • 最終更新: 2026/08/25 20:49
  • by Tana JH1HST