* @link https://getkirby.com * @copyright Bastian Allgeier * @license https://opensource.org/licenses/MIT */ class Txt extends Handler { /** * Converts an array to an encoded Kirby txt string */ public static function encode($data): string { $result = []; foreach (A::wrap($data) as $key => $value) { if (empty($key) === true || $value === null) { continue; } $key = Str::ucfirst(Str::slug($key)); $value = static::encodeValue($value); $result[$key] = static::encodeResult($key, $value); } return implode("\n\n----\n\n", $result); } /** * Helper for converting the value */ protected static function encodeValue(array|string|float $value): string { // avoid problems with certain values $value = match (true) { is_array($value) => Data::encode($value, 'yaml'), is_float($value) => Str::float($value), default => $value }; // escape accidental dividers within a field $value = preg_replace('!(?<=\n|^)----!', '\\----', $value); return $value; } /** * Helper for converting the key and value to the result string */ protected static function encodeResult(string $key, string $value): string { $value = trim($value); $result = $key . ':'; $result .= match (preg_match('!\R!', $value)) { // multi-line content 1 => "\n\n", // single line content, just add space after colon default => ' ', }; $result .= $value; return $result; } /** * Parses a Kirby txt string and returns a multi-dimensional array */ public static function decode($string): array { if ($string === null || $string === '') { return []; } if (is_array($string) === true) { return $string; } if (is_string($string) === false) { throw new InvalidArgumentException( message: 'Invalid TXT data; please pass a string' ); } // remove Unicode BOM at the beginning of the file if (Str::startsWith($string, "\xEF\xBB\xBF") === true) { $string = substr($string, 3); } // explode all fields by the line separator $fields = preg_split('!\n----\s*\n*!', $string); // start the data array $data = []; // loop through all fields and add them to the content foreach ($fields as $field) { if ($pos = strpos($field, ':')) { $key = strtolower(trim(substr($field, 0, $pos))); $key = str_replace(['-', ' '], '_', $key); // Don't add fields with empty keys if (empty($key) === true) { continue; } $value = trim(substr($field, $pos + 1)); // unescape escaped dividers within a field $data[$key] = preg_replace( '!(?<=\n|^)\\\\----!', '----', $value ); } } return $data; } }