くずはすくりぷとPHP+ (ksphp-plus) 及び patTemplate.php
全作業記録 changelog（統合版）
対象：qptns.com/z/ 掲示板一式（bbs.php／bbs.txt, sub/ja, sub/en, sub/patTemplate.php,
      sub/phpzip.inc.php）
記録形式：ISO 8601（分単位）、タイムゾーンはUTC

============================================================
2026-07-16T01:24 UTC
------------------------------------------------------------
【ツリー表示の投稿取りこぼしバグ修正】
対象：sub/ja/bbstree.php, sub/en/bbstree.php

prttreeview()内、本文の「参考：」リンクからREFIDを復元する処理が

    foreach ($thread as $message) { ... $message['REFID'] = ...; }

という値渡しforeachになっており、復元したREFIDが呼び出し元の$threadに
反映されていなかった。この結果、ログ上REFIDフィールドが空で本文の
「参考：」リンクだけが返信元を示している投稿（過去ログ移植等に由来）は、
gentree()の親子判定に一度もヒットせず、ツリー表示から無言で消えていた。

修正：foreach ($thread as $message) を foreach ($thread as &$message) に変更し、
      ループ後に unset($message) を追加。
再現・検証：値渡し／参照渡しでの挙動差を独立の再現スクリプトで確認。


============================================================
2026-07-16T02:14 UTC
------------------------------------------------------------
【スクリプト全体のワーニング一斉対応（第1弾・手動精査ベース）】
対象：bbs.php, sub/ja/{bbsadmin,bbslog,bbstree}.php,
      sub/en/{bbsadmin,bbslog,bbstree}.php

  [1] 未定義配列キー警告：$this->f・$_GET/$_POST/$_COOKIE/$_SERVER/
      $_REQUESTへの無防備アクセス、計184箇所に@を追加。
  [2] null値をstring型関数へ渡すDeprecated警告：trim()/strtolower()/
      crypt()/urlencode()等17箇所を `?? ''` で null安全化
      （数値演算に使う項目は空文字列がTypeErrorを招くため対象外とし、
      NULLのまま@抑止のみとする方針で区別）。
  [3] bbs.php: 動的キー($this->f[$confname])アクセス1箇所を個別に
      null安全化。


============================================================
2026-07-16T16:26 UTC
------------------------------------------------------------
【$checkedfile警告の原因特定・修正、およびPHPStan導入による第2弾監査】
対象：bbs.txt（差分パッチ）, sub/patTemplate.php（07-14版への差分パッチ）,
      sub/ja/bbslog.php, sub/en/bbslog.php, sub/phpzip.inc.php,
      sub/ja/bbstree.php, sub/en/bbstree.php

「Warning: Undefined variable $checkedfile in .../bbs.txt on line 2212」を
きっかけに、bbs.phpがrequire_once("./bbs.txt")のみのシムであり、bbs.txtが
実体（旧bbs.php相当）であることが判明。line 2212は過去ログ自動ZIP化処理の
ガード文で、対象の過去ログ.htmlファイルが1件も無いときに未初期化変数を
参照していたのが原因。

  [1] bbs.txt: $checkedfileをforeachの前に初期化。

ここでPHPStan（静的解析ツール）Level 5を導入し、bbs.txt / sub一式 /
patTemplate.php / phpzip.inc.phpを機械的に再監査。以下を追加で検出・修正：

  [2] bbs.txt: counter()内の $filenumber をforループ前に初期化。
  [3] bbs.txt: conv_imgtag()内の $altvalue をループ先頭で''リセット
      （alt/src属性の無い<img>タグへの値の使い回しという実質的な
      ロジックバグでもあった）。
  [4] sub/{ja,en}/bbstree.php: gentree()呼び出しが参照渡し引数に
      関数の戻り値を直接渡しており"Only variables should be passed
      by reference"Noticeが発生。array_reverse($thread)を一旦変数に
      受けてから渡すよう修正。
  [5] sub/{ja,en}/bbslog.php: 過去ログ一覧の$checkedfileに同型の
      初期化漏れ。念のため対応。
  [6] sub/phpzip.inc.php: GetFileList()内の$fileが未初期化のまま
      array_merge($file, ...)で読み書きされ、TypeError（PHP8では
      致命的エラー）を起こしうる状態だったため初期化。
  [7] sub/patTemplate.php（07-14版からの追加差分、3件）：
      endElementHandler()の$lineno引数不足／addRows()内の
      $newvars・$new_varsタイプミス／getParsedTemplate()での
      $arr未初期化。

ご提供いただいたbbs.txtには独自カスタマイズ（ttp→http自動リンク変換、
gikoneko.php連携フック）が入っていることを確認したため、丸ごと置き換え
ではなく差分パッチとして適用し、保持した。


============================================================
2026-07-16T16:55 UTC
------------------------------------------------------------
【公用／私用パッケージの分離】
コード修正としての新規変更はなし。ご提供いただいた「動作中サブフォルダ
（改造済み）」に対する差分パッチは私用（ksrepair-*.zip）、個人カスタマイズを
一切含まない素のnup0049.zip配布ベースに対する修正版一式は公用
（ks-repair-*.zip）として、以後明確に別ファイル・別zipで扱うことにした。

  ※この直後、公用側の再構築作業でbbs.phpに個人カスタマイズ
    （ttp→http変換・gikoneko.php連携）が誤って混入していたことが判明
    （PHPStan検証用に一時的にbbs.txtをベースにしたプロジェクトを
    そのまま公用側にコピーしてしまったことが原因）。pristineな
    nup0049.zipから修正を再適用し直し、混入ゼロを確認した上で
    公用パッケージを作成した。


============================================================
2026-07-16T17:13 UTC
------------------------------------------------------------
【bbstree.php 新版（indexthreads最適化）への再修正】
対象：sub/ja/bbstree.php

Heyuri/ksphp-plus本家リポジトリの最新版（かぐやさん共有）を新ベースとして
採用。旧走査（スレッド毎にログ全体を毎回再走査・splice）から、ログ全体を
1回だけ走査してスレッドIDごとにバケット化する方式（indexthreads()）に
置き換わっており、大きいログでの速度改善（未読チェックの高速化を含む）が
見込める最適化と判断。2026-07-16のREFID値渡しバグ修正はこのベースに
既に反映済みだった。

新ベースに対して追加で適用した修正：
  [1] $this->f['p']等、@抑止が漏れていた4箇所
  [2] trim(@$this->f['v'])のnull安全化（`?? ''`追加）
  [3] gentree(array_reverse($thread), ...)の参照渡しNotice対策
      （2026-07-16T16:26の他ファイルへの適用と同一の修正）

indexthreads()のロジック自体も確認し、旧コードより順序前提への依存が
減っており堅牢性の面でもむしろ改善されていると判断。ja版のみの提供の
ため、この修正もja版のみ。


============================================================
2026-07-16T21:03 UTC
------------------------------------------------------------
【初回起動時「必須ファイルが無くて落ちる」問題の修正】
対象：bbs.php, sub/ja/bbsadmin.php, sub/en/bbsadmin.php,
      sub/ja/bbsimage.php, sub/en/bbsimage.php,
      sub/ja/lang.php, sub/en/lang.php

bbs.log・upload/id.txtが存在しない状態でアクセス・投稿・削除・画像投稿を
行うと、file_exists()やfopen()が失敗しそのままエラーで停止していた
（新規設置直後や、転送方法によって0バイトファイルが欠落するケースで発生）。

Webappクラスに以下を追加：
  - ensurefile($path, $initialcontent = '')：指定パスが無ければ親
    ディレクトリごと作成して新規作成、既にあれば何もしない。
  - prtfilecreated($messages)：「〇〇が見つからなかったため、新規に
    作成しました。」を表示し、DEFURLが未設定でもCGIURLへフォール
    バックして必ず「掲示板に戻る」リンクを出す専用画面。

適用箇所：bbs.php（loadmessage, putmessage）、bbsadmin.php
（prtkilllist, killmessage）、bbsimage.php（画像アップロード処理の
upload/id.txtオープン前）。

  ※ユーザー入力から組み立てられるファイルパス（過去ログの個別指定等）
    には適用せず、あらかじめ決まっている設定値のみを対象にした。
  ※count/*.dat・bbs.cntは元々fopen()の"w"モードで自動生成される
    設計だったため対象外。

2026-07-16T22:XX、実機（/test/環境）にて「./bbs.logが見つからなかった
ため、新規に作成しました。」の表示・自動生成・「戻る」リンクからの
復帰・投稿フォーム正常表示までを実際に確認済み。


============================================================
2026-07-16T22:18 UTC
------------------------------------------------------------
【Known Bug対応：自分の投稿削除（UNDO）で「見つかりません」エラーに
なることがある問題】
対象：bbs.php: prtundo()

UNDOボタンでの削除時、まれに「消去完了」ではなく「該当記事は見つかり
ませんでした」というエラーになる症状。最有力の原因は「UNDOリンクの
二重クリック・二重送信」で、1回目のリクエストで削除が完了した直後に
2回目が処理されると、Cookieがまだ更新されておらず権限チェックは
通過するが、検索では「もう無い」＝エラーとなっていた。

対応：検索結果が0件の場合を「エラー」ではなく「既に削除済み」として
扱い、通常の削除完了と同じセッション/Cookieクリア処理を行った上で
「消去完了」画面を表示するよう変更。

  ※LOGSAVEローテーションで投稿が過去ログ側に移動していた場合との
    区別はできていない（その場合、実際には削除されていないのに
    「消去完了」と表示される）。二重送信ケースの誤表示解消を優先し、
    区別のための追加対応（過去ログ側も検索対象にする等）は今後の
    検討事項として保留。


============================================================
【参考：コード変更を伴わない調査・報告のみの成果物】
------------------------------------------------------------
- unnecessary-syntax-2026-07-17-01.txt
    公用一式に対する未使用の関数・変数・引数の洗い出し
    （PHPMD + 全関数呼び出し箇所の突き合わせ）。ファイルへの変更なし。


============================================================
2026-07-16T22:36 UTC
------------------------------------------------------------
【本changelogについて】
これまでの個別changelog（ツリー取りこぼし修正、全体ワーニング一斉対応、
$checkedfile／PHPStan監査、公用私用分離、bbstree indexthreads対応、
初回起動時ファイル自動生成、UNDO見つかりませんエラー対応）を1本の
時系列記録に統合したもの。擬古猫さんご自身の掲示板カスタマイズ
（ttp→http自動リンク変換、gikoneko.php連携フック）に関する記述も、
ご希望によりそのまま残してある。
