Symfony convert XLIFF files to another format (e.g. JSON or CSV) - csv

I am using XLIFF files to handle Symfony 5.4 translations but my client would like to convert them to CSV or JSON.
Is it possible to convert my existing files to another format? I don't want to use the extract or update command because this would re-generate the translations. I would prefer to convert my existing ones in another format.
I also tried external tools such as xliff-to-json but they didn't work.

Since I couldn't find a suitable tool I created a console command which converts from XLIFF to CSV:
This is the link to the Gist, please feel free to suggest edits: https://gist.github.com/lukepass/6955d0cf25c44138df24f605e53a96cb
<?php
namespace App\Command;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Translation\Loader\XliffFileLoader;
#[AsCommand(
name: 'app:convert-translations',
description: 'Converts translation files from XLIFF to CSV.'
)]
class ConvertTranslationsCommand extends Command
{
private string $projectDir;
public function __construct(string $projectDir)
{
// best practices recommend to call the parent constructor first and
// then set your own properties. That wouldn't work in this case
// because configure() needs the properties set in this constructor
$this->projectDir = $projectDir;
parent::__construct();
}
protected function configure(): void
{
$this
->addArgument('locale', InputArgument::REQUIRED, 'Locale')
;
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);
/** #var string $locale */
$locale = $input->getArgument('locale');
$translationsDir = $this->projectDir.DIRECTORY_SEPARATOR.'translations';
// takes all the XLIFF files in the translations directory using the Finder component
$finder = new Finder();
$finder->files()->in($translationsDir)->name('*.'.$locale.'.xlf');
if (!$finder->hasResults()) {
$io->error('No XLIFF files found in the translations directory.');
return Command::FAILURE;
}
// iterates over all the XLIFF files found and converts them to CSV
foreach ($finder as $file) {
$xliffFileLoader = new XliffFileLoader();
$messageCatalogue = $xliffFileLoader->load($file->getRealPath(), $locale);
$translations = [];
foreach ($messageCatalogue->all('messages') as $id => $translation) {
$translations[$id] = $translation;
}
// replaces the XLIFF file extension with '.csv'
$csvFilePath = str_replace('.xlf', '.csv', $file->getRealPath());
// creates the CSV file and adds the BOM (Byte Order Mark)
// this is required to make LibreOffice being able to open it
$csvFile = fopen($csvFilePath, 'w');
// writes the actual CSV contents using ';' as the delimiter
foreach ($translations as $id => $translation) {
fputcsv($csvFile, [$id, $translation], ';');
}
fclose($csvFile);
$io->success(sprintf('XLIFF file "%s" converted to CSV.', $file->getFilename()));
}
return Command::SUCCESS;
}
}

Related

SSIS- How to import multiple JSON files in a folder to Oracle?

I am trying to import multiple JSON files in a folder to an Oracle database using SSIS. The code below is the JSON parser that is able to import a single file. I need this to loop through a folder and import all the files. Here is a the code in the script component to import the JSON file. Any ideas? Thank you!
public override void CreateNewOutputRows()
{
String jsonFileContent = File.ReadAllText(#"C:\Users\tngo\File\File1.json");
JavaScriptSerializer js = new JavaScriptSerializer();
List<IGData> igdatas = js.Deserialize<List<IGData>>(jsonFileContent);
foreach (IGData igdata in igdatas)
{
Output0Buffer.AddRow();
Output0Buffer.piececount = igdata.piececount;
Output0Buffer.wgt = igdata.wgt;
}
}
Since you are already in C# you can finish it off there with a foreach loop around your whole code.
string[] files = System.IO.Directory.GetFiles("C:\\Users\\tngo\File\\", "*.json");
foreach(string file in files)
{
String jsonFileContent = File.ReadAllText(file)
JavaScriptSerializer js = new JavaScriptSerializer();
List<IGData> igdatas = js.Deserialize<List<IGData>>(jsonFileContent);
foreach (IGData igdata in igdatas)
{
Output0Buffer.AddRow();
Output0Buffer.piececount = igdata.piececount;
Output0Buffer.wgt = igdata.wgt;
}
}
You'll need to use the Foreach Loop Task.
In the Forech Loop Editor do the following:
Use the Foreach File Enumerator type and point the Folder to C:\Users\tngo\File\. Your Files wildcard will be *.json, and you should check Fully qualified under Retrieve file name. After that, click on Variable Mapping on the left pane of the editor, and create a new string variable that will hold you fully qualified filename. We'll call ours ForEachLoop_StringVar for this example.
After you create the loop, drag your Script Task into the Foreach Loop, and then double click the Script Task to open the Script Task Editor. Add the string variable you created above as a ReadOnlyVariables, and then hit the Edit Script... button to pull up your script. You can then change the hard-coded filename with a reference to your variable. Your script code would then look something like this:
public override void CreateNewOutputRows()
{
String jsonFileContent = File.ReadAllText((string)Dts.Variables["User::ForEachLoop_StringVar"].Value);
JavaScriptSerializer js = new JavaScriptSerializer();
List<IGData> igdatas = js.Deserialize<List<IGData>>(jsonFileContent);
foreach (IGData igdata in igdatas)
{
Output0Buffer.AddRow();
Output0Buffer.piececount = igdata.piececount;
Output0Buffer.wgt = igdata.wgt;
}
}

Is it possible to create a CSV file and make ZIp download in phalcon

I am searching for the CSV file creation in Phalcon .I got some CSV documentation in phalcon but it was not giving clear idea.Can some one post the code for it.Thanks in Advance.
namespace Business\Controllers\API;
use Phalcon\Mvc\Controller;
use Phalcon\Http\Response;
class DownloadController extends \Business\Controllers\API\ApiControllerBase
{
public function createZipAction()
{
// create your zip file
$zipname = 'bvcards.zip';
$zip = new \ZipArchive;
$zip->open($zipname, ZipArchive::CREATE);
echo "here i am";
exit;
}
}
The above code not executing because Zip Archive making some issue.
The same like in PHP. Please check fgetcsv function: http://php.net//manual/en/function.fgetcsv.php
Here is a full example:
$zip = new \ZipArchive();
$filename = 'test.zip';
if ($zip->open($filename, \ZipArchive::CREATE)!==TRUE) {
exit("cannot open <$filename>\n");
}
$zip->addFile('robots.txt', '.htaccess');
$zip->close();
Note the \ before ZipArchive in the open() method. You are missing it and you were probably receiving namespace error.
Please note: in the current example used and generated files are relative to the index.php since in my example this is my bootstrap file. You should set paths according to your configuration.
The below code worked for me .
namespace Business\Controllers\API;
use Phalcon\Mvc\Controller;
use Phalcon\Http\Response;
use ZipArchive;
class DownloadController extends \Business\Controllers\API\ApiControllerBase
{
public function createZipAction()
{
// create your zip file
$zipname = 'bvcards.zip';
$zip = new \ZipArchive;
$zip->open($zipname, ZipArchive::CREATE);
echo "here i am";
exit;
}
}

Accessing config.yml variables in Bolt extensions

I've set up a clean extension and am trying to pull in info from the extension's config.yml file. Config.yml is placed inside the extension folder (at the same level as Extension.php).
At the moment I'm just testing to see if I can retrieve the config. Here's the whole Extension.php:
<?php
namespace Bolt\Extension\andyjessop\vimeo;
use Bolt\Events\CronEvent;
use Bolt\Events\CronEvents;
use Bolt\Application;
use Bolt\BaseExtension;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class Extension extends BaseExtension
{
public function initialize() {
$this->app->get('api/update_video_content', array($this, 'updateVideoContent'))
->bind('updateVideoContent');
}
public function getName()
{
return "vimeo";
}
public function updateVideoContent()
{
$config = $this->config['user_id'];
$response = $this->app->json($config);
return $response;
}
}
And in the config.yml:
access_token: xxxxxxxx
user_id: xxxx
api_base_url: https://api.vimeo.com/
But it returns an empty object. What am I doing wrong here?
Is your config called Config.yml.dist or config.yml.dist - note the capital C, it should be all lowercase? Other than that, after installation of your extension the config.yml.dist will be copied to app/config/extensions/{extensionname}.config.yml and the values in there will be used.

How would I go about loading a JSON file using Laravel?

I have a JSON file that I'd like to load using Laravel. I'm learning Laravel and would like to know the right way to do this. I have the JSON files in a folder called json in the public folder.
In my routes.php I have the following:
Route::get('/json/{jsonfile}', array(
'as' => 'load-json',
'uses' => 'JSONController#loadJSON'
));
In JSONController I have:
public function loadJSON($jsonfile) {
// not sure what to do here
return View::make('json.display')
->with('jsonfile', $jsonfile);
}
Also is my naming convention ok or do you have better suggestions?
Always be careful when allowing a user inputed data to decide what files to read and write. Here is simple code that will take in the filename and look in the apps/storage/json folder. I'm less familiar with what Illuminate does to protect against system injections but you might want at the very least to make sure that 'filename' doesn't contain anything but alphanumeric characters with a validator.
Unless the JSON (or any file) needs to be public you shouldn't keep it in the public folder. This way they must go through your app (and permissions) to view it. Also you can have more restrictive permissions outside the public folder.
public function loadJSON($filename) {
$path = storage_path() . "/json/${filename}.json"; // ie: /var/www/laravel/app/storage/json/filename.json
if (!File::exists($path)) {
throw new Exception("Invalid File");
}
$file = File::get($path); // string
// Verify Validate JSON?
// Your other Stuff
}

How to export data from LinqPAD as JSON?

I want to create a JSON file for use as part of a simple web prototyping exercise. LinqPAD is perfect for accessing the data from my DB in just the shape I need, however I cannot get it out as JSON very easily.
I don't really care what the schema is, because I can adapt my JavaScript to work with whatever is returned.
Is this possible?
A more fluent solution is to add the following methods to the "My Extensions" File in Linqpad:
public static String DumpJson<T>(this T obj)
{
return
obj
.ToJson()
.Dump();
}
public static String ToJson<T>(this T obj)
{
return
new System.Web.Script.Serialization.JavaScriptSerializer()
.Serialize(obj);
}
Then you can use them like this in any query you like:
Enumerable.Range(1, 10)
.Select(i =>
new
{
Index = i,
IndexTimesTen = i * 10,
})
.DumpJson();
I added "ToJson" separately so it can be used in with "Expessions".
This is not directly supported, and I have opened a feature request here. Vote for it if you would also find this useful.
A workaround for now is to do the following:
Set the language to C# Statement(s)
Add an assembly reference (press F4) to System.Web.Extensions.dll
In the same dialog, add a namespace import to System.Web.Script.Serialization
Use code like the following to dump out your query as JSON
new JavaScriptSerializer().Serialize(query).Dump();
There's a solution with Json.NET since it does indented formatting, and renders Json dates properly. Add Json.NET from NuGet, and refer to Newtonsoft.Json.dll to your “My Extensions” query and as well the following code :
public static object DumpJson(this object value, string description = null)
{
return GetJson(value).Dump(description);
}
private static object GetJson(object value)
{
object dump = value;
var strValue = value as string;
if (strValue != null)
{
var obj = JsonConvert.DeserializeObject(strValue);
dump = JsonConvert.SerializeObject(obj, Newtonsoft.Json.Formatting.Indented);
}
else
{
dump = JsonConvert.SerializeObject(value, Newtonsoft.Json.Formatting.Indented);
}
return dump;
}
Use .DumpJson() as .Dump() to render the result. It's possible to override more .DumpJson() with different signatures if necessary.
As of version 4.47, LINQPad has the ability to export JSON built in. Combined with the new lprun.exe utility, it can also satisfy your needs.
http://www.linqpad.net/lprun.aspx