Skip to content

Instantly share code, notes, and snippets.

@lruozzi9
Last active July 26, 2022 15:31
Show Gist options
  • Save lruozzi9/fc44f8f0afa750bd06149d1040674b27 to your computer and use it in GitHub Desktop.
Save lruozzi9/fc44f8f0afa750bd06149d1040674b27 to your computer and use it in GitHub Desktop.
Scripts to export and import messages to a CSV file to simplify the data entry for non-developer people.
<?php
declare(strict_types=1);
use League\Csv\CannotInsertRecord;
use League\Csv\InvalidArgument;
use League\Csv\Writer;
use Symfony\Component\Yaml\Yaml;
const ORIGINAL_MESSAGES_FILE_PATH = 'translations/messages+intl-icu.en.yaml';
const OUPUT_FILE_PATH = 'var/file.csv';
const KEY_COLUMN_HEADER = 'key';
const ORIGINAL_MESSAGE_COLUMN_HEADER = 'original_message';
const CSV_DELIMITER = ',';
require 'config/bootstrap.php';
function getMessagesToTranslateWithFullKey(array $messages, ?string $previousKey = null): array
{
$messagesWithFullKey = [];
foreach ($messages as $key => $message) {
$actualKey = $key;
if ($previousKey !== null) {
$actualKey = sprintf('%s.%s', $previousKey, $key);
}
if (is_array($message)) {
$messagesWithFullKey = array_merge($messagesWithFullKey, getMessagesToTranslateWithFullKey($message, $actualKey));
continue;
}
$messagesWithFullKey[$actualKey] = (string) $message;
}
return $messagesWithFullKey;
}
/**
* @param array<string, string> $records
*
* @throws CannotInsertRecord
* @throws InvalidArgument
*/
function writeFileWithCsvLeague(array $records): void
{
$writer = Writer::createFromPath(OUPUT_FILE_PATH, 'w+');
$writer->setDelimiter(CSV_DELIMITER);
$writer->insertOne([KEY_COLUMN_HEADER, ORIGINAL_MESSAGE_COLUMN_HEADER]);
foreach ($records as $key => $originalMessage) {
$writer->insertOne([$key, $originalMessage]);
}
}
function writeFileWithPlainPHP(array $messagesToTranslate): void
{
$csvContent = KEY_COLUMN_HEADER . CSV_DELIMITER . ORIGINAL_MESSAGE_COLUMN_HEADER . "\n";
foreach ($messagesToTranslate as $key => $originalMessage) {
$csvContent .= $key . CSV_DELIMITER . '"' . str_replace('"', '""', $originalMessage) . '"' . "\n";
}
file_put_contents(OUPUT_FILE_PATH, $csvContent);
}
$originalMessagesFileContents = file_get_contents(ORIGINAL_MESSAGES_FILE_PATH);
if ($originalMessagesFileContents === false) {
throw new InvalidArgumentException('Unable to read from original file, please check if the path is right!');
}
$originalMessages = Yaml::parse($originalMessagesFileContents);
if (!is_array($originalMessages) || count($originalMessages) === 0) {
throw new InvalidArgumentException('File not valid or empty!');
}
$messagesToTranslate = getMessagesToTranslateWithFullKey($originalMessages);
if (class_exists(Writer::class)) {
writeFileWithCsvLeague($messagesToTranslate);
return;
}
writeFileWithPlainPHP($messagesToTranslate);
<?php
declare(strict_types=1);
use League\Csv\Reader;
use Symfony\Component\Yaml\Yaml;
const NEW_MESSAGES_FILE_PATH = 'translations/messages+intl-icu.es.yaml';
const INPUT_FILE_PATH = 'var/file.csv';
const KEY_COLUMN_HEADER = 'key';
const NEW_MESSAGE_COLUMN_HEADER = 'original_message';
const CSV_DELIMITER = ',';
require 'config/bootstrap.php';
/** @return array<string, string> */
function readFileWithCsvLeague(): array
{
$csv = Reader::createFromPath(INPUT_FILE_PATH, 'r');
$csv->setHeaderOffset(0);
$newMessages = [];
foreach ($csv->getRecords() as $record) {
$newMessages[(string) $record[KEY_COLUMN_HEADER]] = (string) $record[NEW_MESSAGE_COLUMN_HEADER];
}
return $newMessages;
}
/** @return array<string, string> */
function readFileWithPlainPHP(): array
{
$newMessages = [];
$row = 0;
$handle = fopen(INPUT_FILE_PATH, 'rb');
if ($handle === false) {
throw new InvalidArgumentException('Unable to open the CSV file! Please, check the path of the file.');
}
$keyColumnNumber = null;
$newMessageColumnNumber = null;
while (($data = fgetcsv($handle, 1000, CSV_DELIMITER)) !== false) {
++$row;
// Skip header
if ($row === 1) {
foreach ($data as $key => $columnHeader) {
if ($columnHeader === KEY_COLUMN_HEADER) {
$keyColumnNumber = $key;
continue;
}
if ($columnHeader === NEW_MESSAGE_COLUMN_HEADER) {
$newMessageColumnNumber = $key;
}
}
if ($keyColumnNumber === null || $newMessageColumnNumber === null) {
throw new InvalidArgumentException('Key column and/or new message column does not exist!');
}
continue;
}
$newMessages[(string) $data[$keyColumnNumber]] = (string) $data[$newMessageColumnNumber];
}
fclose($handle);
return $newMessages;
}
/**
* @param string[] $keys
*/
function indexMessages(array &$indexedMessages, array $keys, string $newMessage): void
{
$currentKey = array_shift($keys);
if ($currentKey === null) {
throw new InvalidArgumentException('Hey 🤨! Something does not work as expected!');
}
if (count($keys) === 0) {
$indexedMessages[$currentKey] = $newMessage;
return;
}
if (!array_key_exists($currentKey, $indexedMessages)) {
$indexedMessages[$currentKey] = [];
}
indexMessages($indexedMessages[$currentKey], $keys, $newMessage);
}
if (class_exists(Reader::class)) {
$newMessages = readFileWithCsvLeague();
} else {
$newMessages = readFileWithPlainPHP();
}
ksort($newMessages);
$indexedMessages = [];
foreach ($newMessages as $messageFullKey => $newMessage) {
$keys = explode('.', $messageFullKey);
indexMessages($indexedMessages, $keys, $newMessage);
}
$fileContent = Yaml::dump($indexedMessages, 100);
file_put_contents(NEW_MESSAGES_FILE_PATH, $fileContent);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment