差分
このページの2つのバージョン間の差分を表示します。
| 次のリビジョン | 前のリビジョン | ||
| 48th_8j1ham_rs [2026/08/25 20:49] – 作成 Tana JH1HST | 48th_8j1ham_rs [2026/08/27 03:54] (現在) – Tana JH1HST | ||
|---|---|---|---|
| 行 1: | 行 1: | ||
| + | ~~NOCACHE~~ | ||
| + | |||
| ====== 8J1HAM 会場公開運用 当選確認 ====== | ====== 8J1HAM 会場公開運用 当選確認 ====== | ||
| + | |||
| + | 第48回アマチュア無線フェスティバル ハムフェア2026 | ||
| 特別記念局 **8J1HAM 会場公開運用**へ多数のお申し込みをいただき、ありがとうございました。 | 特別記念局 **8J1HAM 会場公開運用**へ多数のお申し込みをいただき、ありがとうございました。 | ||
| - | 下の入力欄に、**お申し込み時に登録したコールサインまたはメールアドレス**を入力して、選考結果をご確認ください。 | + | 下の入力欄に、**お申し込み時に登録したコールサインまたはメールアドレス**を入力して、抽選結果をご確認ください。 |
| 体験運用でお申し込みの方など、コールサインを登録していない場合は、**お申し込み時のメールアドレス**を入力してください。 | 体験運用でお申し込みの方など、コールサインを登録していない場合は、**お申し込み時のメールアドレス**を入力してください。 | ||
| 行 19: | 行 23: | ||
| return ' | return ' | ||
| } | } | ||
| + | |||
| if ($date === ' | if ($date === ' | ||
| return ' | return ' | ||
| } | } | ||
| + | |||
| return $date; | return $date; | ||
| } | } | ||
| 行 27: | 行 33: | ||
| echo ' | echo ' | ||
| < | < | ||
| - | .hf-result-wrap { | + | |
| + | #hf-result-wrap { | ||
| + | width: 100%; | ||
| max-width: 760px; | max-width: 760px; | ||
| - | margin: | + | margin: |
| + | 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: | border-radius: | ||
| - | padding: 20px; | + | padding: 20px 20px 20px 24px; |
| margin: 20px 0; | margin: 20px 0; | ||
| } | } | ||
| - | .hf-search-label { | + | #hf-search-form { |
| - | display: block; | + | display: block !important; |
| - | | + | |
| - | margin-bottom: 8px; | + | margin: 0 !important; |
| + | padding: 0 !important; | ||
| + | border: 0 !important; | ||
| + | background: transparent !important; | ||
| + | box-shadow: none !important; | ||
| + | border-radius: | ||
| + | position: static !important; | ||
| } | } | ||
| - | .hf-search-row { | + | #hf-search-form:: |
| - | display: | + | # |
| - | | + | display: |
| - | flex-wrap: wrap; | + | |
| } | } | ||
| - | .hf-search-input { | + | #hf-search-form label { |
| - | | + | |
| - | | + | |
| - | padding: | + | padding: |
| - | font-size: 16px; | + | font-weight: bold !important; |
| - | border: 1px solid #aaa; | + | |
| - | border-radius: | + | |
| } | } | ||
| - | .hf-search-button | + | #hf-search-form input[type=" |
| - | | + | |
| - | | + | |
| - | | + | |
| - | | + | |
| - | border: 0; | + | |
| - | border-radius: | + | margin: 0 6px 12px 6px !important; |
| - | | + | padding: 11px 12px !important; |
| - | | + | border: 1px solid #999 !important; |
| + | border-radius: | ||
| + | | ||
| + | | ||
| } | } | ||
| - | .hf-search-button: | + | #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: | ||
| + | background: #1769aa !important; | ||
| + | color: #fff !important; | ||
| + | font-size: 16px !important; | ||
| + | font-weight: | ||
| + | cursor: pointer !important; | ||
| } | } | ||
| - | .hf-small { | + | #hf-search-form button: |
| - | color: #666; | + | background: #0d568e !important; |
| - | font-size: 0.92em; | + | } |
| - | margin-top: 10px; | + | |
| + | # | ||
| + | display: block !important; | ||
| + | margin: 10px 6px 0 6px !important; | ||
| + | padding: 0 !important; | ||
| + | color: #666 !important; | ||
| + | font-size: 0.92em | ||
| } | } | ||
| .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: | ||
| + | margin-bottom: | ||
| + | } | ||
| + | |||
| + | .hf-cancelled { | ||
| + | width: 100%; | ||
| + | box-sizing: border-box; | ||
| + | margin: 24px 0; | ||
| + | padding: 22px; | ||
| + | background: #fff4e5; | ||
| + | border: 2px solid #e0a24a; | ||
| + | border-radius: | ||
| + | } | ||
| + | |||
| + | .hf-cancelled-title { | ||
| + | color: #b06000; | ||
| + | font-size: 1.25em; | ||
| font-weight: | font-weight: | ||
| margin-bottom: | margin-bottom: | ||
| 行 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: | border-left: | ||
| 行 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: | border-left: | ||
| } | } | ||
| + | |||
| + | @media screen and (max-width: 600px) { | ||
| + | |||
| + | # | ||
| + | padding-left: | ||
| + | } | ||
| + | |||
| + | # | ||
| + | .hf-winner, | ||
| + | .hf-not-selected, | ||
| + | .hf-cancelled { | ||
| + | padding: 16px; | ||
| + | } | ||
| + | |||
| + | # | ||
| + | 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; | ||
| + | } | ||
| + | } | ||
| + | |||
| </ | </ | ||
| - | < | + | < |
| - | <form method=" | + | |
| - | <label class=" | + | |
| - | コールサイン または メールアドレス | + | |
| - | </label> | + | |
| - | | + | |
| - | <input | + | |
| - | type=" | + | |
| - | | + | |
| - | name=" | + | |
| - | class=" | + | |
| - | value="" | + | |
| - | autocomplete=" | + | |
| - | required | + | |
| - | > | + | |
| - | <button type=" | + | |
| - | 当選結果を確認する | + | |
| - | </ | + | |
| - | </div> | + | |
| - | | + | <label for=" |
| - | お申し込み時に登録した内容を入力してください。部分一致ではなく完全一致で確認します。 | + | コールサイン または メールアドレス |
| - | </ | + | </ |
| - | </ | + | |
| + | <input | ||
| + | type=" | ||
| + | id=" | ||
| + | name=" | ||
| + | autocomplete=" | ||
| + | autocapitalize=" | ||
| + | spellcheck=" | ||
| + | maxlength=" | ||
| + | pattern=" | ||
| + | title=" | ||
| + | required | ||
| + | > | ||
| + | |||
| + | <button type=" | ||
| + | 当選結果を確認する | ||
| + | </ | ||
| + | |||
| + | | ||
| + | お申し込み時に登録した内容を入力してください。部分一致ではなく完全一致で確認します。 | ||
| + | </ | ||
| + | |||
| + | | ||
| + | |||
| + | < | ||
| + | document.addEventListener(" | ||
| + | |||
| + | var input = document.getElementById(" | ||
| + | |||
| + | if (!input) { | ||
| + | return; | ||
| + | } | ||
| + | |||
| + | input.addEventListener(" | ||
| + | |||
| + | this.value = this.value.normalize(" | ||
| + | |||
| + | }); | ||
| + | |||
| + | }); | ||
| + | </script> | ||
| '; | '; | ||
| if ($_SERVER[' | if ($_SERVER[' | ||
| - | $input = isset($_POST[' | + | $input = isset($_POST[' |
| + | | ||
| + | | ||
| + | |||
| + | if (function_exists(' | ||
| + | $input = mb_convert_kana($input, | ||
| + | } | ||
| + | |||
| + | $input = strtr( | ||
| + | $input, | ||
| + | array( | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ) | ||
| + | ); | ||
| if ($input === '' | if ($input === '' | ||
| + | |||
| echo ' | echo ' | ||
| <div class=" | <div class=" | ||
| 行 200: | 行 336: | ||
| </ | </ | ||
| '; | '; | ||
| + | |||
| + | } elseif (preg_match('/ | ||
| + | |||
| + | echo ' | ||
| + | <div class=" | ||
| + | < | ||
| + | コールサインまたはメールアドレスを半角英数字で入力してください。 | ||
| + | </ | ||
| + | '; | ||
| + | |||
| } elseif (!is_file($db_file)) { | } elseif (!is_file($db_file)) { | ||
| + | |||
| echo ' | echo ' | ||
| <div class=" | <div class=" | ||
| - | 現在、選考結果データを読み込むことができません。 | + | 現在、抽選結果データを読み込むことができません。 |
| しばらくしてから再度お試しください。 | しばらくしてから再度お試しください。 | ||
| </ | </ | ||
| '; | '; | ||
| + | |||
| } else { | } else { | ||
| try { | try { | ||
| + | |||
| $pdo = new PDO( | $pdo = new PDO( | ||
| ' | ' | ||
| 行 220: | 行 369: | ||
| ); | ); | ||
| - | /* | ||
| - | * コールサインは大文字小文字を区別せず、 | ||
| - | * メールアドレスも大文字小文字を区別せず完全一致。 | ||
| - | */ | ||
| $callsign_norm = strtoupper($input); | $callsign_norm = strtoupper($input); | ||
| $email_norm | $email_norm | ||
| - | /* | ||
| - | * まず「申込そのものが存在するか」を確認。 | ||
| - | * | ||
| - | * 同一メールアドレスで複数申込が存在する場合もあるため、 | ||
| - | * 1件に限定せず applicant_id を取得する。 | ||
| - | */ | ||
| $stmt = $pdo-> | $stmt = $pdo-> | ||
| ' | ' | ||
| 行 240: | 行 379: | ||
| ); | ); | ||
| - | $stmt-> | + | $stmt-> |
| - | ': | + | |
| - | ': | + | ': |
| - | )); | + | ': |
| + | ) | ||
| + | | ||
| $applicants = $stmt-> | $applicants = $stmt-> | ||
| 行 259: | 行 400: | ||
| $ids = array(); | $ids = array(); | ||
| + | |||
| foreach ($applicants as $applicant) { | foreach ($applicants as $applicant) { | ||
| $ids[] = $applicant[' | $ids[] = $applicant[' | ||
| } | } | ||
| - | | + | $placeholders = implode( |
| - | * 一致した申込IDの中に当選結果があるか確認。 | + | |
| - | * 重複申込があった場合でも、当選している申込を拾える。 | + | |
| - | */ | + | |
| - | | + | |
| $stmt = $pdo-> | $stmt = $pdo-> | ||
| - | ' | + | ' |
| - | callsign, | + | |
| - | email, | + | callsign, |
| - | date, | + | email, |
| - | start_time, | + | date, |
| - | end_time, | + | start_time, |
| - | band, | + | end_time, |
| - | operation_type, | + | band, |
| - | slot_type | + | operation_type, |
| - | | + | slot_type, |
| - | WHERE applicant_id IN (' . $placeholders . ') | + | status |
| - | ORDER BY date, start_time' | + | |
| + | | ||
| + | | ||
| ); | ); | ||
| $stmt-> | $stmt-> | ||
| + | |||
| $results = $stmt-> | $results = $stmt-> | ||
| 行 290: | 行 434: | ||
| foreach ($results as $result) { | foreach ($results as $result) { | ||
| + | |||
| + | /* | ||
| + | * キャンセル済み | ||
| + | */ | ||
| + | if ( | ||
| + | isset($result[' | ||
| + | && $result[' | ||
| + | ) { | ||
| + | |||
| + | $date_text = hf_date_jp($result[' | ||
| + | |||
| + | $time_text = | ||
| + | $result[' | ||
| + | . ' | ||
| + | . $result[' | ||
| + | |||
| + | echo ' | ||
| + | <div class=" | ||
| + | |||
| + | <div class=" | ||
| + | この運用枠はキャンセル済みです。 | ||
| + | </ | ||
| + | |||
| + | <table class=" | ||
| + | |||
| + | <tr> | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | </tr> | ||
| + | |||
| + | <tr> | ||
| + | |||
| + | < | ||
| + | . hf_h($date_text) | ||
| + | . '</ | ||
| + | |||
| + | < | ||
| + | . hf_h($time_text) | ||
| + | . '</ | ||
| + | |||
| + | <td> | ||
| + | < | ||
| + | . hf_h($result[' | ||
| + | . '</ | ||
| + | </td> | ||
| + | |||
| + | <td> | ||
| + | < | ||
| + | </td> | ||
| + | |||
| + | </tr> | ||
| + | |||
| + | </ | ||
| + | |||
| + | <p> | ||
| + | キャンセルとして受け付けています。 | ||
| + | </p> | ||
| + | |||
| + | </ | ||
| + | '; | ||
| + | |||
| + | continue; | ||
| + | } | ||
| $date_text = hf_date_jp($result[' | $date_text = hf_date_jp($result[' | ||
| - | | + | |
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| echo ' | echo ' | ||
| 行 298: | 行 511: | ||
| <div class=" | <div class=" | ||
| - | おめでとうございます。選考の結果、当選しました。 | + | おめでとうございます。抽選の結果、当選しました。 |
| </ | </ | ||
| <table class=" | <table class=" | ||
| + | |||
| <tr> | <tr> | ||
| < | < | ||
| 行 308: | 行 522: | ||
| < | < | ||
| </tr> | </tr> | ||
| + | |||
| <tr> | <tr> | ||
| - | | + | |
| - | < | + | |
| - | < | + | |
| - | <td class=" | + | |
| + | |||
| + | < | ||
| + | | ||
| + | | ||
| + | |||
| + | <td> | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | |||
| + | <td class=" | ||
| + | | ||
| + | | ||
| </tr> | </tr> | ||
| + | |||
| </ | </ | ||
| '; | '; | ||
| if (!empty($result[' | if (!empty($result[' | ||
| + | |||
| echo ' | echo ' | ||
| <p> | <p> | ||
| コールサイン: | コールサイン: | ||
| - | < | + | < |
| + | | ||
| + | | ||
| </p> | </p> | ||
| '; | '; | ||
| + | |||
| } else { | } else { | ||
| - | /* | + | |
| - | * 体験運用などコールサインがない場合は、 | + | |
| - | * メールアドレスをそのまま再表示せず、 | + | |
| - | | + | |
| - | | + | |
| + | if (count($parts) === 2) { | ||
| + | |||
| + | $local | ||
| + | $domain = $parts[1]; | ||
| + | |||
| + | if ($local !== '' | ||
| + | $masked = | ||
| + | substr($local, | ||
| + | . '***@' | ||
| + | . $domain; | ||
| + | } else { | ||
| + | $masked = '***@' . $domain; | ||
| + | } | ||
| + | |||
| + | } else { | ||
| + | |||
| + | $masked = $email; | ||
| + | } | ||
| echo ' | echo ' | ||
| <p> | <p> | ||
| - | | + | |
| + | < | ||
| + | . hf_h($masked) | ||
| + | . '</ | ||
| </p> | </p> | ||
| '; | '; | ||
| 行 338: | 行 595: | ||
| if ( | if ( | ||
| - | $result[' | + | $result[' |
| + | | ||
| $result[' | $result[' | ||
| ) { | ) { | ||
| + | |||
| echo ' | echo ' | ||
| <p> | <p> | ||
| 行 351: | 行 610: | ||
| echo ' | echo ' | ||
| <div class=" | <div class=" | ||
| - | | + | |
| + | | ||
| + | | ||
| + | | ||
| < | < | ||
| - | | + | |
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| 8J1HAM 会場公開運用 当選者向けガイド | 8J1HAM 会場公開運用 当選者向けガイド | ||
| </a> | </a> | ||
| + | |||
| </ | </ | ||
| 行 368: | 行 637: | ||
| <div class=" | <div class=" | ||
| - | 厳正なる選考の結果、今回は残念ながら運用枠をご用意することができませんでした。 | + | 厳正なる抽選の結果、今回は残念ながら運用枠をご用意することができませんでした。 |
| </ | </ | ||
| 行 382: | 行 651: | ||
| } catch (Exception $e) { | } catch (Exception $e) { | ||
| - | /* | ||
| - | * DBの内部エラー内容は公開画面には表示しない。 | ||
| - | */ | ||
| echo ' | echo ' | ||
| <div class=" | <div class=" | ||
| - | 選考結果の確認中にエラーが発生しました。 | + | |
| しばらくしてから再度お試しください。 | しばらくしてから再度お試しください。 | ||
| </ | </ | ||
| 行 395: | 行 661: | ||
| } | } | ||
| - | echo '</ | + | echo ' |
| + | </ | ||
| + | '; | ||
| </ | </ | ||