|
| 1 | +import { ILoader } from "./_types"; |
| 2 | +import { createLoader } from "./_utils"; |
| 3 | +import { fromString } from "php-array-reader"; |
| 4 | + |
| 5 | +export default function createPhpLoader(): ILoader<string, Record<string, any>> { |
| 6 | + return createLoader({ |
| 7 | + pull: async (locale, input) => { |
| 8 | + try { |
| 9 | + const output = fromString(input); |
| 10 | + return output; |
| 11 | + } catch (error) { |
| 12 | + throw new Error(`Error parsing PHP file for locale ${locale}`); |
| 13 | + } |
| 14 | + }, |
| 15 | + push: async (locale, data, originalInput) => { |
| 16 | + const output = toPhpString(data, originalInput); |
| 17 | + return output; |
| 18 | + }, |
| 19 | + }); |
| 20 | +} |
| 21 | + |
| 22 | +function toPhpString(data: Record<string, any>, originalPhpString: string | null) { |
| 23 | + const defaultFilePrefix = "<?php\n\n"; |
| 24 | + if (originalPhpString) { |
| 25 | + const [filePrefix = defaultFilePrefix] = originalPhpString.split("return "); |
| 26 | + const shortArraySyntax = !originalPhpString.includes("array("); |
| 27 | + const output = `${filePrefix}return ${toPhpArray(data, shortArraySyntax)};`; |
| 28 | + return output; |
| 29 | + } |
| 30 | + return `${defaultFilePrefix}return ${toPhpArray(data)};`; |
| 31 | +} |
| 32 | + |
| 33 | +function toPhpArray(data: any, shortSyntax = true, indentLevel = 1): string { |
| 34 | + if (data === null || data === undefined) { |
| 35 | + return "null"; |
| 36 | + } |
| 37 | + if (typeof data === "string") { |
| 38 | + return `'${escapePhpString(data)}'`; |
| 39 | + } |
| 40 | + if (typeof data === "number") { |
| 41 | + return data.toString(); |
| 42 | + } |
| 43 | + if (typeof data === "boolean") { |
| 44 | + return data ? "true" : "false"; |
| 45 | + } |
| 46 | + |
| 47 | + const arrayStart = shortSyntax ? "[" : "array("; |
| 48 | + const arrayEnd = shortSyntax ? "]" : ")"; |
| 49 | + |
| 50 | + if (Array.isArray(data)) { |
| 51 | + return `${arrayStart}\n${data |
| 52 | + .map((value) => `${indent(indentLevel)}${toPhpArray(value, shortSyntax, indentLevel + 1)}`) |
| 53 | + .join(",\n")}\n${indent(indentLevel - 1)}${arrayEnd}`; |
| 54 | + } |
| 55 | + |
| 56 | + const output = `${arrayStart}\n${Object.entries(data) |
| 57 | + .map(([key, value]) => `${indent(indentLevel)}'${key}' => ${toPhpArray(value, shortSyntax, indentLevel + 1)}`) |
| 58 | + .join(",\n")}\n${indent(indentLevel - 1)}${arrayEnd}`; |
| 59 | + return output; |
| 60 | +} |
| 61 | + |
| 62 | +function indent(level: number) { |
| 63 | + return " ".repeat(level); |
| 64 | +} |
| 65 | + |
| 66 | +function escapePhpString(str: string) { |
| 67 | + return str |
| 68 | + .replaceAll("\\", "\\\\") |
| 69 | + .replaceAll("'", "\\'") |
| 70 | + .replaceAll("\r", "\\r") |
| 71 | + .replaceAll("\n", "\\n") |
| 72 | + .replaceAll("\t", "\\t"); |
| 73 | +} |
0 commit comments