FailedRowsWriter
in package
CSVインポートで失敗した行を、修正して再アップロードできる1本のCSVへ逐次書き出す
「登録・更新自体が失敗した行」と「登録・更新は成功したが再試行可能なメディア取込のみ 失敗した行」の両方を対象にする。元CSVに再インポート用の識別子列がなければ追加し、DB上に実在するIDが あればその値を入れる。末尾には acms_error_reason(失敗理由)のみを追加する。
Why not 全行をメモリに貯めてから書き出さないか: CSV全体(成功行含む)を貯めるわけではなく 失敗した行だけが対象のため件数は限定的だが、行ごとに逐次ローカル一時ファイルへ追記する 設計にして、既存の Csv::run() の逐次処理モデルと一貫させる(メモリ膨張を避ける)。
Why not PrivateStorage への逐次書き込みにしないか: Storage 抽象化層(ローカル/クラウド)は put()(全内容を一度に書く)しか持たず、追記ストリームを提供しない。ローカルの一時ファイルへ 逐次 fputcsv() で追記し、finalize() で内容をまとめて PrivateStorage::put() へ渡す (MediaSourceImporter の「一時ファイル→ストレージ」という既存パターンに合わせる)。
Table of Contents
Constants
- COLUMN_ENTRY_ID = 'entry_id'
- エントリーCSVの再インポート時に更新対象を指定する標準列名
- COLUMN_ERROR_REASON = 'acms_error_reason'
- 失敗理由を記録する予約列名
Properties
- $handle : resource|null
- $identifierColumn : non-empty-string
- $localTempPath : string
- $outputLabels : array<int, string>|null
- $rowCount : int
Methods
- __construct() : mixed
- addRow() : void
- 失敗した1行を追記する
- discard() : void
- ローカル一時ファイルを削除する(正常終了・異常終了問わず呼び出し側から必ず呼ぶこと)
- escapeFormulaInjection() : string
- CSV数式インジェクション対策: 先頭が =+-@ の値は、表計算ソフトに数式として解釈させないため 先頭に str-data_ を付与する
- finalize() : bool
- 蓄積した内容を PrivateStorage 上の $storagePath へ書き出す
- hasRows() : bool
- closeHandle() : void
- ensureOpen() : resource
- writeCsvLine() : void
Constants
COLUMN_ENTRY_ID
エントリーCSVの再インポート時に更新対象を指定する標準列名
public
mixed
COLUMN_ENTRY_ID
= 'entry_id'
COLUMN_ERROR_REASON
失敗理由を記録する予約列名
public
mixed
COLUMN_ERROR_REASON
= 'acms_error_reason'
Properties
$handle
private
resource|null
$handle
= null
$identifierColumn read-only
private
non-empty-string
$identifierColumn
= self::COLUMN_ENTRY_ID
再インポート時に更新対象を指定する列名
$localTempPath read-only
private
string
$localTempPath
$outputLabels
private
array<int, string>|null
$outputLabels
= null
確定済みの出力列順(元列+識別子列+失敗理由)
$rowCount
private
int
$rowCount
= 0
Methods
__construct()
public
__construct(string $localTempPath[, string $identifierColumn = self::COLUMN_ENTRY_ID ]) : mixed
Parameters
- $localTempPath : string
- $identifierColumn : string = self::COLUMN_ENTRY_ID
addRow()
失敗した1行を追記する
public
addRow(array<int, string> $labels, array<string, string> $dataByLabel, int|null $recordId, string $errorReason) : void
Parameters
- $labels : array<int, string>
-
元CSVの列名(順序を保持するため連想配列ではなく配列で受け取る)
- $dataByLabel : array<string, string>
-
列名 => 値(Model::getData() の戻り値)
- $recordId : int|null
-
DB上に実在するID(無ければ null)
- $errorReason : string
-
失敗理由
discard()
ローカル一時ファイルを削除する(正常終了・異常終了問わず呼び出し側から必ず呼ぶこと)
public
discard() : void
escapeFormulaInjection()
CSV数式インジェクション対策: 先頭が =+-@ の値は、表計算ソフトに数式として解釈させないため 先頭に str-data_ を付与する
public
static escapeFormulaInjection(string $value) : string
Why not シングルクォート付与にしないか: この失敗行CSVは「表計算ソフトで開く」だけでなく 「修正してそのままa-blog cmsへ再アップロードする」ことも想定入力のため、再取込時に 元へ戻せる必要がある。シングルクォートは表計算ソフトの慣習的な文字列強制記法だが a-blog cms側に対応する復元処理が無く、値に '=SUM(A1)' がそのまま保存されてしまう。 str-data_ は既存のCSVインポート仕様(Model::normalize() が取り込み時に必ず除去する。 csv.html の説明文にも記載)で、表計算ソフトからは先頭が文字扱いになり数式実行を防げる うえ、再取込時にa-blog cms側で自動的に剥がれる。
Parameters
- $value : string
Return values
stringfinalize()
蓄積した内容を PrivateStorage 上の $storagePath へ書き出す
public
finalize(string $storagePath) : bool
1件も追記が無かった場合は何もせず false を返す(呼び出し側は失敗行CSVを 生成しない扱いにできる)。成否によらずローカル一時ファイルは削除する。
Parameters
- $storagePath : string
Return values
bool —書き出しを行った場合 true
hasRows()
public
hasRows() : bool
Return values
boolcloseHandle()
private
closeHandle() : void
ensureOpen()
private
ensureOpen() : resource
Return values
resourcewriteCsvLine()
private
writeCsvLine(array<int, string> $values) : void
Parameters
- $values : array<int, string>