Small PHP 8.4 CLI that walks an input tree, reads third-party CSV exports (app, deviceToken, deviceTokenStatus, tags), maps app display names to codes using var/appCodes.ini, normalizes pipe-separated tags into three status columns, and writes UTF-8 CSV output (streamed reads/writes). The -e / --extensions option only controls which files are selected (by extension); every selected file is opened and parsed as CSV (e.g. use csv to process only *.csv in a folder that also contains .xml or .xls).
- PHP 8.4+
- Composer
composer installRuntime data lives under var/: uploads in var/input, exports in var/output, and the app-name map in var/appCodes.ini. Input/output directories are git-ignored except empty placeholder folders; appCodes.ini is tracked so mappings ship with the project. Override -i / -o when needed.
Run via Composer’s bin proxy or PHP directly:
php bin/process --help
php bin/process -d
php bin/process -i var/input -o var/output
php bin/process -i var/input -o var/output -m -f
composer test| Flag / option | Meaning |
|---|---|
-i / --input |
Input directory (default: var/input) |
-o / --output |
Output directory (default: var/output) |
-e / --extensions |
Which file extensions to include when searching the tree: * (all files) or a comma-separated list without dots (default: csv). Each included file is read as CSV. Example: csv picks only *.csv when the folder mixes CSV, XML, and spreadsheets. |
-m / --merge |
Write one file, merged.csv, instead of mirroring the tree. Default (no -m): keep input-relative paths and write one CSV per matched input file under --output. |
-d / --dry-run |
Validate inputs only (no CSV output, no error log file, no empty-output check). |
-f / --force |
After validation issues, continue without prompting (needed in CI / non-TTY). |
- Real runs require an empty output directory (or the tool creates it if missing). If the directory already contains files, the command exits with an error so nothing is overwritten silently.
- Validation runs first (full stream over all CSV rows). If there are warnings or errors, an interactive prompt appears on a TTY; otherwise use
-fto proceed or fix data first. - Outputs: by default, mirrored mode writes one CSV per input file (same relative paths as under
--input). With-m/--merge, a singlemerged.csvis written instead. A detailed log is written toprocessing-errors.login the output directory; warnings/errors also surface on stderr during processing. - Tags → three status columns: Pipe-separated tokens in
tagsare classified into subscription, free product, and IAP groups using the allow-lists and per-group priority insrc/Services/DeviceRowMapper.php(seeSUBSCRIPTION_PRIORITY,FREE_PRODUCT_PRIORITY,IAP_PRODUCT_PRIORITY). A column is empty when no token in that row belongs to that group (or thetagscell is empty). Unrecognized tokens are still logged at DEBUG and listed in context; they do not fill a status column until the token is added to those lists.
composer test
# or
vendor/bin/phpunit- league/csv — streaming CSV
- nategood/commando — CLI options
- monolog/monolog — file + stderr logging