From 6f91c3cbf0cd6200228cf4dc5b691a246d0138bb Mon Sep 17 00:00:00 2001 From: Mustafa Ehsan Date: Mon, 30 May 2016 22:01:53 +0430 Subject: [PATCH 01/37] Initial commit for export command --- composer.json | 3 +- src/Commands/ExportCommand.php | 111 +++++++++++++++++++++++++++++++++ src/LangmanServiceProvider.php | 1 + tests/ExportCommandTest.php | 12 ++++ 4 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 src/Commands/ExportCommand.php create mode 100644 tests/ExportCommandTest.php diff --git a/composer.json b/composer.json index 9dbc86a..8ce6b3d 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,8 @@ "php": "^5.5.9 || ^7.0", "illuminate/support": "5.1.* || 5.2.*", "illuminate/console": "5.1.* || 5.2.*", - "illuminate/filesystem": "5.1.* || 5.2.*" + "illuminate/filesystem": "5.1.* || 5.2.*", + "league/csv": "^8.0" }, "require-dev": { "phpunit/phpunit" : "^4.8 || ^5.0", diff --git a/src/Commands/ExportCommand.php b/src/Commands/ExportCommand.php new file mode 100644 index 0000000..b0eb06d --- /dev/null +++ b/src/Commands/ExportCommand.php @@ -0,0 +1,111 @@ +manager = $manager; + } + + /** + * Execute the console command. + * + * @return mixed + */ + public function handle() + { + $csv = Writer::createFromFileObject(new \SplFileObject(storage_path('somefile.csv'), 'w')); + + $header = array_merge(['Language File', 'Key'], $this->manager->languages()); + $csv->insertOne($header); + + $langFiles = $this->manager->files(); + + $langArray = []; + + $filesContent = []; + + foreach($langFiles as $langFileName => $langFilePath) { + foreach ($langFilePath as $languageKey => $file) { + foreach ($filesContent[$languageKey] = Arr::dot($this->manager->getFileContent($file)) as $key => $value) { + $langArray[$langFileName][$key]['key'] = $key; + $langArray[$langFileName][$key][$languageKey] = $value; + } + } + } + + $content = []; + + foreach ($langArray as $langName => $langProps) { + $langProps = array_values($langProps); + + foreach ($langProps as $langRow) { + $row = [$langName]; + $row[] = $langRow['key']; + + foreach ($this->manager->languages() as $language) { + try { + if (is_array($langRow[$language])) { + $row[] = ''; + } else { + $row[] = $langRow[$language]; + } + } catch(\ErrorException $ex) { + $row[] = ''; + } + } + $content[] = $row; + } + } +// dd($content); + $csv->insertAll($content); + + $csv->output(); + + $this->info('CSV file generated successfully.'); + } +} diff --git a/src/LangmanServiceProvider.php b/src/LangmanServiceProvider.php index f0c4c2d..6cf920e 100644 --- a/src/LangmanServiceProvider.php +++ b/src/LangmanServiceProvider.php @@ -36,6 +36,7 @@ public function register() \Themsaid\Langman\Commands\ShowCommand::class, \Themsaid\Langman\Commands\FindCommand::class, \Themsaid\Langman\Commands\SyncCommand::class, + \Themsaid\Langman\Commands\ExportCommand::class ]); } } diff --git a/tests/ExportCommandTest.php b/tests/ExportCommandTest.php new file mode 100644 index 0000000..d5d6def --- /dev/null +++ b/tests/ExportCommandTest.php @@ -0,0 +1,12 @@ + Date: Tue, 31 May 2016 00:05:22 +0430 Subject: [PATCH 02/37] Add config file. Refactoring ExportCommand class --- config/langman.php | 12 +++++ src/Commands/ExportCommand.php | 87 +++++++++++++++++++++++++++++----- 2 files changed, 87 insertions(+), 12 deletions(-) diff --git a/config/langman.php b/config/langman.php index f5cee0c..f5d0165 100644 --- a/config/langman.php +++ b/config/langman.php @@ -12,4 +12,16 @@ */ 'path' => realpath(base_path('resources/lang')), + + /* + * -------------------------------------------------------------------------- + * Path to the directory where CSV files should be exported + * -------------------------------------------------------------------------- + * + * This option determines where to put the exported CSV files. This directory + * must be writable by server. By default storage/langman-csv directory + * will be used. + */ + + 'csv_path' => storage_path('langman-csv'), ]; diff --git a/src/Commands/ExportCommand.php b/src/Commands/ExportCommand.php index b0eb06d..dcd9a48 100644 --- a/src/Commands/ExportCommand.php +++ b/src/Commands/ExportCommand.php @@ -3,6 +3,7 @@ namespace Themsaid\Langman\Commands; use Illuminate\Console\Command; +use Illuminate\Contracts\Filesystem\Filesystem; use Illuminate\Support\Arr; use League\Csv\Writer; use Themsaid\Langman\Manager; @@ -15,7 +16,8 @@ class ExportCommand extends Command * * @var string */ - protected $signature = 'langman:export {export-to=csv}'; + protected $signature = 'langman:export + {--P|path= : The location where the CSV file should be exported.}'; /** * The name and signature of the console command. @@ -31,6 +33,13 @@ class ExportCommand extends Command */ private $manager; + /** + * The Languages manager instance. + * + * @var \Illuminate\Contracts\Filesystem\Filesystem + */ + protected $filesystem; + /** * Array of files grouped by filename. * @@ -41,14 +50,16 @@ class ExportCommand extends Command /** * ListCommand constructor. * - * @param \Themsaid\LangMan\Manager $manager + * @param \Themsaid\LangMan\Manager $manager + * @param \Illuminate\Contracts\Filesystem\Filesystem * @return void */ - public function __construct(Manager $manager) + public function __construct(Manager $manager, Filesystem $filesystem) { parent::__construct(); $this->manager = $manager; + $this->filesystem = $filesystem; } /** @@ -58,18 +69,74 @@ public function __construct(Manager $manager) */ public function handle() { - $csv = Writer::createFromFileObject(new \SplFileObject(storage_path('somefile.csv'), 'w')); + $path = $this->generateCsvFile($this->option('path')); + + $this->info('CSV file successfully generated in ' . $path .'.'); + } + + private function generateCsvFile($path = null) + { + $csvPath = $this->getCsvPath($path); + + $csv = Writer::createFromFileObject(new \SplFileObject($csvPath, 'w')); + + $header = $this->getHeaderContent(); + $content = $this->getBodyContent(); - $header = array_merge(['Language File', 'Key'], $this->manager->languages()); $csv->insertOne($header); + $csv->insertAll($content); + + $csv->output(); + + return $csvPath; + } + + private function getCsvPath($path) + { + $exportDir = is_null($path) ? config('langman.csv_path') : base_path($path); + + if (! $this->filesystem->exists($exportDir)) { + $this->filesystem->makeDirectory($exportDir); + } + return $exportDir . '/' . $this->getDatePrefix() . '_langman.csv'; + } + + /* + * Get the date prefix for the CSV file. + * + * @return string + */ + protected function getDatePrefix() + { + return date('Y_m_d_His'); + } + + /** + * Get the CSV header content. + * + * @return array + */ + protected function getHeaderContent() + { + return array_merge(['Language File', 'Key'], $this->manager->languages()); + } + + /** + * Get the CSV rows content. + * + * @return array + * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException + */ + protected function getBodyContent() + { $langFiles = $this->manager->files(); $langArray = []; $filesContent = []; - foreach($langFiles as $langFileName => $langFilePath) { + foreach ($langFiles as $langFileName => $langFilePath) { foreach ($langFilePath as $languageKey => $file) { foreach ($filesContent[$languageKey] = Arr::dot($this->manager->getFileContent($file)) as $key => $value) { $langArray[$langFileName][$key]['key'] = $key; @@ -94,18 +161,14 @@ public function handle() } else { $row[] = $langRow[$language]; } - } catch(\ErrorException $ex) { + } catch (\ErrorException $ex) { $row[] = ''; } } $content[] = $row; } } -// dd($content); - $csv->insertAll($content); - - $csv->output(); - $this->info('CSV file generated successfully.'); + return $content; } } From 683e4984697a494a86a80475a3e374e6b2374adc Mon Sep 17 00:00:00 2001 From: Mustafa Ehsan Alokozay Date: Wed, 1 Jun 2016 00:51:19 +0430 Subject: [PATCH 03/37] Fix Arabic/Persian UTF8 issues in CSV. Some refactoring. --- src/Commands/ExportCommand.php | 93 ++++++++++++++++++++++------------ src/Manager.php | 24 +++++++++ 2 files changed, 84 insertions(+), 33 deletions(-) diff --git a/src/Commands/ExportCommand.php b/src/Commands/ExportCommand.php index dcd9a48..9ae1fa8 100644 --- a/src/Commands/ExportCommand.php +++ b/src/Commands/ExportCommand.php @@ -6,6 +6,7 @@ use Illuminate\Contracts\Filesystem\Filesystem; use Illuminate\Support\Arr; use League\Csv\Writer; +use League\Csv\Reader; use Themsaid\Langman\Manager; use Illuminate\Support\Str; @@ -74,23 +75,64 @@ public function handle() $this->info('CSV file successfully generated in ' . $path .'.'); } + /** + * Generates a CSV file from translations files and putting it in + * the given path. + * + * @param string|null $path + * @return string + */ private function generateCsvFile($path = null) { $csvPath = $this->getCsvPath($path); - $csv = Writer::createFromFileObject(new \SplFileObject($csvPath, 'w')); + $this->writeContentToCsvFile($this->getHeaderContent(), $this->getBodyContent(), $csvPath); - $header = $this->getHeaderContent(); - $content = $this->getBodyContent(); + return $csvPath; + } - $csv->insertOne($header); - $csv->insertAll($content); + /** + * Creating a CSV file from the given content into the given file. + * + * @param $header + * @param $content + * @param $filepath + * @return void + */ + protected function writeContentToCsvFile($header, $content, $filepath) + { + array_unshift($content, $header); - $csv->output(); + $file = fopen($filepath, 'w'); + $csvText = ''; - return $csvPath; + foreach($content as $csvRecord) { + // Fields containing line breaks (CRLF), double quotes, and commas should be + // enclosed in double-quotes. We need this to escape commas and other + // special CSV characters. + $csvRecord = array_map(function($element) { + return '"' . $element . '"'; + }, $csvRecord); + + // Here we create a CSV record from an array record. + $csvText .= implode(',', $csvRecord) . "\n"; + } + + // These lines handle encoding issues. They make sure that a CSV file + // is properly rendered in most of the CSV reader tools. + mb_convert_encoding($csvText, 'UTF-16LE', 'UTF-8'); + fprintf($file, "\xEF\xBB\xBF"); + + fputs($file, $csvText); + fclose($file); } + /** + * Get the file path for the CSV file. + * + * @param $path + * @return string + */ private function getCsvPath($path) { $exportDir = is_null($path) ? config('langman.csv_path') : base_path($path); @@ -130,41 +172,26 @@ protected function getHeaderContent() */ protected function getBodyContent() { - $langFiles = $this->manager->files(); - - $langArray = []; - - $filesContent = []; - - foreach ($langFiles as $langFileName => $langFilePath) { - foreach ($langFilePath as $languageKey => $file) { - foreach ($filesContent[$languageKey] = Arr::dot($this->manager->getFileContent($file)) as $key => $value) { - $langArray[$langFileName][$key]['key'] = $key; - $langArray[$langFileName][$key][$languageKey] = $value; - } - } - } - + $langFiles = $this->manager->getFilesContentGroupedByFilenameAndKey(); $content = []; - foreach ($langArray as $langName => $langProps) { - $langProps = array_values($langProps); - - foreach ($langProps as $langRow) { - $row = [$langName]; - $row[] = $langRow['key']; + foreach ($langFiles as $langFileName => $langProps) { + foreach ($langProps as $key => $translations) { + $row = [$langFileName, $key]; foreach ($this->manager->languages() as $language) { + // If an UndefinedIndex Exception was thrown, it means that $key + // does not have translation in the $language, so we will + // handle it by just assigning it to an empty string try { - if (is_array($langRow[$language])) { - $row[] = ''; - } else { - $row[] = $langRow[$language]; - } + // If a translation is just an array (empty), it means that it doesn't have + // any translation so we will skip it by assigning it an empty string. + $row[] = is_array($translations[$language]) ? '' : $translations[$language]; } catch (\ErrorException $ex) { $row[] = ''; } } + $content[] = $row; } } diff --git a/src/Manager.php b/src/Manager.php index 002d9f1..d180be1 100644 --- a/src/Manager.php +++ b/src/Manager.php @@ -365,4 +365,28 @@ public function getKeysExistingInALanguageButNotTheOther($values) return $missing; } + + /** + * Get all language files content as an array grouped by their filename + * and their key. + * + * @return array + * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException + */ + public function getFilesContentGroupedByFilenameAndKey() + { + $allLangs = []; + $filesContent = []; + + foreach ($this->files() as $langFileName => $langFilePath) { + foreach ($langFilePath as $languageKey => $file) { + foreach ($filesContent[$languageKey] = Arr::dot($this->getFileContent($file)) as $key => $value) { + $allLangs[$langFileName][$key]['key'] = $key; + $allLangs[$langFileName][$key][$languageKey] = $value; + } + } + } + + return $allLangs; + } } From c8a830faa925fdf00bb1cc1e9c38959bd1920ac0 Mon Sep 17 00:00:00 2001 From: Mustafa Ehsan Alokozay Date: Wed, 1 Jun 2016 15:55:37 +0430 Subject: [PATCH 04/37] Add only and exclude options. Some Refactoring. --- src/Commands/ExportCommand.php | 47 ++++++++++++++++++++++++++++------ src/Manager.php | 5 ++-- 2 files changed, 42 insertions(+), 10 deletions(-) diff --git a/src/Commands/ExportCommand.php b/src/Commands/ExportCommand.php index 9ae1fa8..3791a09 100644 --- a/src/Commands/ExportCommand.php +++ b/src/Commands/ExportCommand.php @@ -4,11 +4,7 @@ use Illuminate\Console\Command; use Illuminate\Contracts\Filesystem\Filesystem; -use Illuminate\Support\Arr; -use League\Csv\Writer; -use League\Csv\Reader; use Themsaid\Langman\Manager; -use Illuminate\Support\Str; class ExportCommand extends Command { @@ -18,7 +14,9 @@ class ExportCommand extends Command * @var string */ protected $signature = 'langman:export - {--P|path= : The location where the CSV file should be exported.}'; + {--P|path= : The location where the CSV file should be exported.} + {--only= : Specify the file(s) you want to export to CSV} + {--exclude= : File(s) you do not want to export to CSV}'; /** * The name and signature of the console command. @@ -75,6 +73,37 @@ public function handle() $this->info('CSV file successfully generated in ' . $path .'.'); } + /** + * Filter files based on user options + * + * @return array|string + */ + protected function filterFilesForCsvExport() + { + if (! is_null($this->option('only')) && ! is_null($this->option('exclude'))) { + $this->error('You cannot combine --only and --exclude options. Please use one of them.'); + exit(); + } + + $availableFiles = $this->manager->files(); + + if (! is_null($this->option('only'))) { + $onlyFiles = explode(',', $this->option('only')); + + // We will only return files for those keys which a file exist for. + return array_intersect_key($this->manager->files(), array_combine($onlyFiles, $onlyFiles)); + } + + if (! is_null($this->option('exclude'))) { + $excludeFiles = explode(',', $this->option('exclude')); + + // We will only return files for those keys which a file exist for. + return array_diff_key($this->manager->files(), array_combine($excludeFiles, $excludeFiles)); + } + + return null; + } + /** * Generates a CSV file from translations files and putting it in * the given path. @@ -86,7 +115,9 @@ private function generateCsvFile($path = null) { $csvPath = $this->getCsvPath($path); - $this->writeContentToCsvFile($this->getHeaderContent(), $this->getBodyContent(), $csvPath); + $userSelectedFiles = $this->filterFilesForCsvExport(); + + $this->writeContentToCsvFile($this->getHeaderContent(), $this->getBodyContent($userSelectedFiles), $csvPath); return $csvPath; } @@ -170,9 +201,9 @@ protected function getHeaderContent() * @return array * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException */ - protected function getBodyContent() + protected function getBodyContent($files) { - $langFiles = $this->manager->getFilesContentGroupedByFilenameAndKey(); + $langFiles = $this->manager->getFilesContentGroupedByFilenameAndKey($files); $content = []; foreach ($langFiles as $langFileName => $langProps) { diff --git a/src/Manager.php b/src/Manager.php index d180be1..09b24e7 100644 --- a/src/Manager.php +++ b/src/Manager.php @@ -373,12 +373,13 @@ public function getKeysExistingInALanguageButNotTheOther($values) * @return array * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException */ - public function getFilesContentGroupedByFilenameAndKey() + public function getFilesContentGroupedByFilenameAndKey(array $selectedFiles = null) { + $files = is_null($selectedFiles) ? $this->files() : $selectedFiles; $allLangs = []; $filesContent = []; - foreach ($this->files() as $langFileName => $langFilePath) { + foreach ($files as $langFileName => $langFilePath) { foreach ($langFilePath as $languageKey => $file) { foreach ($filesContent[$languageKey] = Arr::dot($this->getFileContent($file)) as $key => $value) { $allLangs[$langFileName][$key]['key'] = $key; From c3fe0686d2e45f58a3b350743efcc2023a384f8a Mon Sep 17 00:00:00 2001 From: Mustafa Ehsan Alokozay Date: Wed, 1 Jun 2016 20:00:22 +0430 Subject: [PATCH 05/37] Moving functions to right place --- src/Commands/ExportCommand.php | 38 +++++++++++++++++----------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/Commands/ExportCommand.php b/src/Commands/ExportCommand.php index 3791a09..1d5aa19 100644 --- a/src/Commands/ExportCommand.php +++ b/src/Commands/ExportCommand.php @@ -73,6 +73,24 @@ public function handle() $this->info('CSV file successfully generated in ' . $path .'.'); } + /** + * Generates a CSV file from translations files and putting it in + * the given path. + * + * @param string|null $path + * @return string + */ + protected function generateCsvFile($path = null) + { + $csvPath = $this->getCsvPath($path); + + $userSelectedFiles = $this->filterFilesForCsvExport(); + + $this->writeContentToCsvFile($this->getHeaderContent(), $this->getBodyContent($userSelectedFiles), $csvPath); + + return $csvPath; + } + /** * Filter files based on user options * @@ -104,24 +122,6 @@ protected function filterFilesForCsvExport() return null; } - /** - * Generates a CSV file from translations files and putting it in - * the given path. - * - * @param string|null $path - * @return string - */ - private function generateCsvFile($path = null) - { - $csvPath = $this->getCsvPath($path); - - $userSelectedFiles = $this->filterFilesForCsvExport(); - - $this->writeContentToCsvFile($this->getHeaderContent(), $this->getBodyContent($userSelectedFiles), $csvPath); - - return $csvPath; - } - /** * Creating a CSV file from the given content into the given file. * @@ -164,7 +164,7 @@ protected function writeContentToCsvFile($header, $content, $filepath) * @param $path * @return string */ - private function getCsvPath($path) + protected function getCsvPath($path) { $exportDir = is_null($path) ? config('langman.csv_path') : base_path($path); From 172721a41fc2adc319e07b886afaa19b422f3845 Mon Sep 17 00:00:00 2001 From: Mustafa Ehsan Alokozay Date: Fri, 29 Jul 2016 11:43:35 +0430 Subject: [PATCH 06/37] Add import feature --- src/Commands/ExportCommand.php | 13 +-- src/Commands/ImportCommand.php | 154 +++++++++++++++++++++++++++++++++ src/LangmanServiceProvider.php | 3 +- src/Manager.php | 13 ++- src/Support/Arr.php | 43 +++++++++ tests/ExportCommandTest.php | 12 --- tests/ManagerTest.php | 73 ++++++++++++++++ tests/TestCase.php | 2 +- tests/temp/.gitignore | 2 - tests/temp/en/users.php | 7 ++ tests/temp/nl/users.php | 2 + untitled.php | 0 12 files changed, 296 insertions(+), 28 deletions(-) create mode 100644 src/Commands/ImportCommand.php create mode 100644 src/Support/Arr.php delete mode 100644 tests/ExportCommandTest.php delete mode 100644 tests/temp/.gitignore create mode 100644 tests/temp/en/users.php create mode 100644 tests/temp/nl/users.php create mode 100644 untitled.php diff --git a/src/Commands/ExportCommand.php b/src/Commands/ExportCommand.php index 1d5aa19..6d135ef 100644 --- a/src/Commands/ExportCommand.php +++ b/src/Commands/ExportCommand.php @@ -103,23 +103,18 @@ protected function filterFilesForCsvExport() exit(); } - $availableFiles = $this->manager->files(); + $onlyFiles = []; if (! is_null($this->option('only'))) { - $onlyFiles = explode(',', $this->option('only')); - - // We will only return files for those keys which a file exist for. - return array_intersect_key($this->manager->files(), array_combine($onlyFiles, $onlyFiles)); + $onlyFiles = array_keys($this->manager->files(explode(',', $this->option('only')))); } if (! is_null($this->option('exclude'))) { $excludeFiles = explode(',', $this->option('exclude')); - - // We will only return files for those keys which a file exist for. - return array_diff_key($this->manager->files(), array_combine($excludeFiles, $excludeFiles)); + $onlyFiles = array_diff(array_keys($this->manager->files()), $excludeFiles); } - return null; + return $onlyFiles; } /** diff --git a/src/Commands/ImportCommand.php b/src/Commands/ImportCommand.php new file mode 100644 index 0000000..4238534 --- /dev/null +++ b/src/Commands/ImportCommand.php @@ -0,0 +1,154 @@ +manager = $manager; + $this->filesystem = $filesystem; + } + + /** + * Execute the console command. + * + * @return mixed + */ + public function handle() + { + $csvFileContents = $this->getCsvFileContents(); + + $filesToBeChanged = join("\n\t", array_keys(array_first($csvFileContents))); + + if (! $this->confirm("The following files will be overridden: \n\t" . $filesToBeChanged . "\nAre you sure?")) { + $this->line('No files changed.'); + exit(); + } + + $this->writeToLangFiles($csvFileContents); + + $this->info('Import complete.'); + } + + protected function getCsvFileContents() + { + if (is_null($this->option('path'))) { + if (is_null($fileName = $this->argument('filename'))) { + $this->error('No path specified.'); + exit(); + } else { + $filePath = config('langman.csv_path') .DIRECTORY_SEPARATOR. $fileName; + } + } else { + $filePath = base_path($this->option('path')); + } + + if (! file_exists($filePath)) { + $this->error('No such file found: ' . $filePath); + exit(); + } + + return $this->readCsvFileContents($filePath); + } + + protected function readCsvFileContents($filePath) + { + $csv = array_map('str_getcsv', file($filePath)); + + // Get header content + $langDirs = array_slice(array_shift($csv), 2); + + $groupedByDirName = []; + + foreach ($langDirs as $index => $langDir) { + $groupedByFileNames = []; + $trans = []; + $langDirName = ''; + foreach ($csv as $langRow) { + if ($langDirName != '' && $langDirName != $langRow[0]) { + $trans = []; + } + $langDirName = $langRow[0]; + $langKey = $langRow[1]; + + $langIndex = $index+2; + $trans[$langKey] = $langRow[$langIndex]; + + $groupedByFileNames[$langDirName] = $trans; + } + + $groupedByDirName[$langDir] = $groupedByFileNames; + } + + return $groupedByDirName; + } + + protected function writeToLangFiles($data) + { + foreach ($data as $langDirName => $langDirContent) { + $langDirPath = config('langman.path') . DIRECTORY_SEPARATOR . $langDirName; + + if (! $this->filesystem->exists($langDirPath)) { + $this->filesystem->makeDirectory($langDirPath); + } + + foreach ($langDirContent as $fileName => $fileContent) { + $fileContent = Arr::unDot($fileContent); + $fileContent = "disk->allFiles($this->path)); @@ -81,6 +81,12 @@ public function files() if (! Str::contains($this->path, 'vendor')) { $filesByFile = $this->neglectVendorFiles($filesByFile); } + + $fileNames = (array) $fileNames; + + if (! empty($fileNames)) { + return array_intersect_key($filesByFile, array_combine($fileNames, $fileNames)); + } return $filesByFile; } @@ -373,9 +379,10 @@ public function getKeysExistingInALanguageButNotTheOther($values) * @return array * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException */ - public function getFilesContentGroupedByFilenameAndKey(array $selectedFiles = null) + public function getFilesContentGroupedByFilenameAndKey($selectedFiles = []) { - $files = is_null($selectedFiles) ? $this->files() : $selectedFiles; + $files = $this->files((array) $selectedFiles); + $allLangs = []; $filesContent = []; diff --git a/src/Support/Arr.php b/src/Support/Arr.php new file mode 100644 index 0000000..db0e867 --- /dev/null +++ b/src/Support/Arr.php @@ -0,0 +1,43 @@ + $value) { + if (count($dottedKeys = explode('.', $key, 2)) > 1) { + $results[$dottedKeys[0]][$dottedKeys[1]] = $value; + } else { + $results[$key] = $value; + } + } + + if ($recursively) { + foreach ($results as $key => $value) { + if (is_array($value) && ! empty($value)) { + $results[$key] = self::undot($value, $recursively); + } + } + } + + return $results; + } +} \ No newline at end of file diff --git a/tests/ExportCommandTest.php b/tests/ExportCommandTest.php deleted file mode 100644 index d5d6def..0000000 --- a/tests/ExportCommandTest.php +++ /dev/null @@ -1,12 +0,0 @@ - __DIR__.'/temp/vendor/package/sp/user.php', // ], ]; + + $expectedUserOnly = [ + 'user' => [ + 'en' => __DIR__.DIRECTORY_SEPARATOR.'temp'.DIRECTORY_SEPARATOR.'en'.DIRECTORY_SEPARATOR.'user.php', + 'nl' => __DIR__.DIRECTORY_SEPARATOR.'temp'.DIRECTORY_SEPARATOR.'nl'.DIRECTORY_SEPARATOR.'user.php', + ] + ]; $this->assertEquals($expected, $manager->files()); + $this->assertEquals($expectedUserOnly, $manager->files('user')); } public function testLanguagesMethod() @@ -266,4 +274,69 @@ public function testGetKeysExistingInALanguageButNotTheOther() $this->assertNotContains('user.address:en', $results); $this->assertNotContains('user.address:nl', $results); } + + public function testGetFilesContentGroupedByFilenameAndKeyMethod() + { + $manager = $this->app[\Themsaid\Langman\Manager::class]; + + $filesList = [ + 'en' => [ + 'user' => " ['not_found' => 'user not found'], 'edit-user' => 'Edit User'];", + 'category' => " ['cat-not-found' => 'category not found'], 'edit-cat' => 'Edit Category'];", + ], + 'fr' => [ + 'user' => " ['not_found' => 'french user not found'], 'edit-user' => 'French Edit User'];", + 'category' => " ['cat-not-found' => 'french category not found'], 'edit-cat' => 'French Edit Category'];", + ] + ]; + + $expected = [ + 'user' => [ + 'missing.not_found' => [ + 'key' => 'missing.not_found', + 'en' => 'user not found', + 'fr' => 'french user not found' + ], + 'edit-user' => [ + 'key' => 'edit-user', + 'en' => 'Edit User', + 'fr' => 'French Edit User' + ] + ], + 'category' => [ + 'category-missing.cat-not-found' => [ + 'key' => 'category-missing.cat-not-found', + 'en' => 'category not found', + 'fr' => 'french category not found' + ], + 'edit-cat' => [ + 'key' => 'edit-cat', + 'en' => 'Edit Category', + 'fr' => 'French Edit Category' + ] + ] + ]; + + $expectedUserOnly = [ + 'user' => [ + 'missing.not_found' => [ + 'key' => 'missing.not_found', + 'en' => 'user not found', + 'fr' => 'french user not found' + ], + 'edit-user' => [ + 'key' => 'edit-user', + 'en' => 'Edit User', + 'fr' => 'French Edit User' + ] + ] + ]; + + $this->createTempFiles($filesList); + + $this->assertEquals($expected, $manager->getFilesContentGroupedByFilenameAndKey()); + $this->assertEquals($expected, $manager->getFilesContentGroupedByFilenameAndKey([])); + $this->assertEquals($expectedUserOnly, $manager->getFilesContentGroupedByFilenameAndKey(['user'])); + $this->assertEquals($expectedUserOnly, $manager->getFilesContentGroupedByFilenameAndKey('user')); + } } diff --git a/tests/TestCase.php b/tests/TestCase.php index 9e94e0b..f7844f8 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -26,7 +26,7 @@ public function tearDown() { parent::tearDown(); - exec('rm -rf '.__DIR__.'/temp/*'); +// exec('rm -rf '.__DIR__.'/temp/*'); $this->consoleOutput = ''; } diff --git a/tests/temp/.gitignore b/tests/temp/.gitignore deleted file mode 100644 index d6b7ef3..0000000 --- a/tests/temp/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/tests/temp/en/users.php b/tests/temp/en/users.php new file mode 100644 index 0000000..8bf56f3 --- /dev/null +++ b/tests/temp/en/users.php @@ -0,0 +1,7 @@ + [ + 'first' => 'name', + ], +]; \ No newline at end of file diff --git a/tests/temp/nl/users.php b/tests/temp/nl/users.php new file mode 100644 index 0000000..b2f4336 --- /dev/null +++ b/tests/temp/nl/users.php @@ -0,0 +1,2 @@ + Date: Fri, 29 Jul 2016 11:51:42 +0430 Subject: [PATCH 07/37] Change from CSV to Excel --- src/Commands/ExportCommand.php | 28 ++++++++++++++-------------- untitled.php | 0 2 files changed, 14 insertions(+), 14 deletions(-) delete mode 100644 untitled.php diff --git a/src/Commands/ExportCommand.php b/src/Commands/ExportCommand.php index 6d135ef..689e815 100644 --- a/src/Commands/ExportCommand.php +++ b/src/Commands/ExportCommand.php @@ -14,16 +14,16 @@ class ExportCommand extends Command * @var string */ protected $signature = 'langman:export - {--P|path= : The location where the CSV file should be exported.} - {--only= : Specify the file(s) you want to export to CSV} - {--exclude= : File(s) you do not want to export to CSV}'; + {--P|path= : The location where the exported file should be exported.} + {--only= : Specify the file(s) you want to export to Excel} + {--exclude= : File(s) you do not want to export to Excel}'; /** * The name and signature of the console command. * * @var string */ - protected $description = 'Generates a CSV file from your language files'; + protected $description = 'Generates a Excel file from your language files'; /** * The Languages manager instance. @@ -68,27 +68,27 @@ public function __construct(Manager $manager, Filesystem $filesystem) */ public function handle() { - $path = $this->generateCsvFile($this->option('path')); + $path = $this->generateExcelFile($this->option('path')); - $this->info('CSV file successfully generated in ' . $path .'.'); + $this->info('Excel file successfully generated in ' . $path .'.'); } /** - * Generates a CSV file from translations files and putting it in + * Generates an Excel file from translations files and putting it in * the given path. * * @param string|null $path * @return string */ - protected function generateCsvFile($path = null) + protected function generateExcelFile($path = null) { - $csvPath = $this->getCsvPath($path); + $filePath = $this->getFilePath($path); - $userSelectedFiles = $this->filterFilesForCsvExport(); + $userSelectedFiles = $this->filterFilesForExport(); - $this->writeContentToCsvFile($this->getHeaderContent(), $this->getBodyContent($userSelectedFiles), $csvPath); + $this->writeContentToCsvFile($this->getHeaderContent(), $this->getBodyContent($userSelectedFiles), $filePath); - return $csvPath; + return $filePath; } /** @@ -96,7 +96,7 @@ protected function generateCsvFile($path = null) * * @return array|string */ - protected function filterFilesForCsvExport() + protected function filterFilesForExport() { if (! is_null($this->option('only')) && ! is_null($this->option('exclude'))) { $this->error('You cannot combine --only and --exclude options. Please use one of them.'); @@ -159,7 +159,7 @@ protected function writeContentToCsvFile($header, $content, $filepath) * @param $path * @return string */ - protected function getCsvPath($path) + protected function getFilePath($path) { $exportDir = is_null($path) ? config('langman.csv_path') : base_path($path); diff --git a/untitled.php b/untitled.php deleted file mode 100644 index e69de29..0000000 From 5428139bd87b5856459637299c89876bcf582b40 Mon Sep 17 00:00:00 2001 From: Mustafa Ehsan Alokozay Date: Mon, 8 Aug 2016 15:00:53 +0430 Subject: [PATCH 08/37] Add PHPExcel --- composer.json | 2 +- src/Commands/ExportCommand.php | 61 +++++++++++++++++++++------------- 2 files changed, 39 insertions(+), 24 deletions(-) diff --git a/composer.json b/composer.json index 8ce6b3d..be60d53 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,7 @@ "illuminate/support": "5.1.* || 5.2.*", "illuminate/console": "5.1.* || 5.2.*", "illuminate/filesystem": "5.1.* || 5.2.*", - "league/csv": "^8.0" + "phpoffice/phpexcel": "^1.8" }, "require-dev": { "phpunit/phpunit" : "^4.8 || ^5.0", diff --git a/src/Commands/ExportCommand.php b/src/Commands/ExportCommand.php index 689e815..cf55179 100644 --- a/src/Commands/ExportCommand.php +++ b/src/Commands/ExportCommand.php @@ -86,7 +86,7 @@ protected function generateExcelFile($path = null) $userSelectedFiles = $this->filterFilesForExport(); - $this->writeContentToCsvFile($this->getHeaderContent(), $this->getBodyContent($userSelectedFiles), $filePath); + $this->writeContentsToFile($this->getHeaderContent(), $this->getBodyContent($userSelectedFiles), $filePath); return $filePath; } @@ -118,39 +118,54 @@ protected function filterFilesForExport() } /** - * Creating a CSV file from the given content into the given file. + * Creating a Excel file from the given content. * * @param $header * @param $content * @param $filepath * @return void */ - protected function writeContentToCsvFile($header, $content, $filepath) + protected function writeContentsToFile($header, $content, $filepath) { array_unshift($content, $header); - $file = fopen($filepath, 'w'); - $csvText = ''; + $excelObj = new \PHPExcel(); + $excelObj->getProperties() + ->setTitle('Laravel Langman Exported Language File') + ->setSubject('Laravel Langman Exported Language File') + ->setCreator('Laravel Langman'); - foreach($content as $csvRecord) { - // Fields containing line breaks (CRLF), double quotes, and commas should be - // enclosed in double-quotes. We need this to escape commas and other - // special CSV characters. - $csvRecord = array_map(function($element) { - return '"' . $element . '"'; - }, $csvRecord); - - // Here we create a CSV record from an array record. - $csvText .= implode(',', $csvRecord) . "\n"; + foreach ($content as $record) { + dd($record); } - // These lines handle encoding issues. They make sure that a CSV file - // is properly rendered in most of the CSV reader tools. - mb_convert_encoding($csvText, 'UTF-16LE', 'UTF-8'); - fprintf($file, "\xEF\xBB\xBF"); - - fputs($file, $csvText); - fclose($file); + $writer = \PHPExcel_IOFactory::createWriter($excelObj, 'Excel2007'); + $writer->save($filepath); +// +// $writer = new PHPExcel(); +// $writer->save($filepath); +// $file = fopen($filepath, 'w'); +// $csvText = ''; +// +// foreach($content as $csvRecord) { +// // Fields containing line breaks (CRLF), double quotes, and commas should be +// // enclosed in double-quotes. We need this to escape commas and other +// // special CSV characters. +// $csvRecord = array_map(function($element) { +// return '"' . $element . '"'; +// }, $csvRecord); +// +// // Here we create a CSV record from an array record. +// $csvText .= implode(',', $csvRecord) . "\n"; +// } +// +// // These lines handle encoding issues. They make sure that a CSV file +// // is properly rendered in most of the CSV reader tools. +// mb_convert_encoding($csvText, 'UTF-16LE', 'UTF-8'); +// fprintf($file, "\xEF\xBB\xBF"); +// +// fputs($file, $csvText); +// fclose($file); } /** @@ -167,7 +182,7 @@ protected function getFilePath($path) $this->filesystem->makeDirectory($exportDir); } - return $exportDir . '/' . $this->getDatePrefix() . '_langman.csv'; + return $exportDir . '/' . $this->getDatePrefix() . '_langman.xlsx'; } /* From b359a9c369347595fcfc057aa1d46888dbc0c4f2 Mon Sep 17 00:00:00 2001 From: Mustafa Ehsan Alokozay Date: Mon, 8 Aug 2016 16:16:18 +0430 Subject: [PATCH 09/37] Complete CSV to Excel export conversion --- config/langman.php | 8 +++--- src/Commands/ExportCommand.php | 51 +++++++--------------------------- 2 files changed, 14 insertions(+), 45 deletions(-) diff --git a/config/langman.php b/config/langman.php index f5d0165..55864dc 100644 --- a/config/langman.php +++ b/config/langman.php @@ -15,13 +15,13 @@ /* * -------------------------------------------------------------------------- - * Path to the directory where CSV files should be exported + * Path to the directory where Excel files should be exported * -------------------------------------------------------------------------- * - * This option determines where to put the exported CSV files. This directory - * must be writable by server. By default storage/langman-csv directory + * This option determines where to put the exported Excel files. This directory + * must be writable by server. By default storage/langman directory * will be used. */ - 'csv_path' => storage_path('langman-csv'), + 'exports_path' => storage_path('langman-exports'), ]; diff --git a/src/Commands/ExportCommand.php b/src/Commands/ExportCommand.php index cf55179..e9af036 100644 --- a/src/Commands/ExportCommand.php +++ b/src/Commands/ExportCommand.php @@ -32,13 +32,6 @@ class ExportCommand extends Command */ private $manager; - /** - * The Languages manager instance. - * - * @var \Illuminate\Contracts\Filesystem\Filesystem - */ - protected $filesystem; - /** * Array of files grouped by filename. * @@ -53,12 +46,11 @@ class ExportCommand extends Command * @param \Illuminate\Contracts\Filesystem\Filesystem * @return void */ - public function __construct(Manager $manager, Filesystem $filesystem) + public function __construct(Manager $manager) { parent::__construct(); $this->manager = $manager; - $this->filesystem = $filesystem; } /** @@ -135,37 +127,14 @@ protected function writeContentsToFile($header, $content, $filepath) ->setSubject('Laravel Langman Exported Language File') ->setCreator('Laravel Langman'); + $rowNumber = 1; foreach ($content as $record) { - dd($record); + $excelObj->getActiveSheet()->fromArray($record, '', 'A'. $rowNumber); + $rowNumber++; } $writer = \PHPExcel_IOFactory::createWriter($excelObj, 'Excel2007'); $writer->save($filepath); -// -// $writer = new PHPExcel(); -// $writer->save($filepath); -// $file = fopen($filepath, 'w'); -// $csvText = ''; -// -// foreach($content as $csvRecord) { -// // Fields containing line breaks (CRLF), double quotes, and commas should be -// // enclosed in double-quotes. We need this to escape commas and other -// // special CSV characters. -// $csvRecord = array_map(function($element) { -// return '"' . $element . '"'; -// }, $csvRecord); -// -// // Here we create a CSV record from an array record. -// $csvText .= implode(',', $csvRecord) . "\n"; -// } -// -// // These lines handle encoding issues. They make sure that a CSV file -// // is properly rendered in most of the CSV reader tools. -// mb_convert_encoding($csvText, 'UTF-16LE', 'UTF-8'); -// fprintf($file, "\xEF\xBB\xBF"); -// -// fputs($file, $csvText); -// fclose($file); } /** @@ -176,17 +145,17 @@ protected function writeContentsToFile($header, $content, $filepath) */ protected function getFilePath($path) { - $exportDir = is_null($path) ? config('langman.csv_path') : base_path($path); + $exportDir = is_null($path) ? config('langman.exports_path') : base_path($path); - if (! $this->filesystem->exists($exportDir)) { - $this->filesystem->makeDirectory($exportDir); + if (! file_exists($exportDir)) { + mkdir($exportDir, 0755); } return $exportDir . '/' . $this->getDatePrefix() . '_langman.xlsx'; } /* - * Get the date prefix for the CSV file. + * Get the date prefix for the Excel file. * * @return string */ @@ -196,7 +165,7 @@ protected function getDatePrefix() } /** - * Get the CSV header content. + * Get the Excel header content. * * @return array */ @@ -206,7 +175,7 @@ protected function getHeaderContent() } /** - * Get the CSV rows content. + * Get the Excel body content from language files. * * @return array * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException From cc32d6800412860ab424ece3a40ce084b008ea57 Mon Sep 17 00:00:00 2001 From: Mustafa Ehsan Alokozay Date: Thu, 11 Aug 2016 09:34:17 +0430 Subject: [PATCH 10/37] Change from CSV to Excel --- src/Commands/ImportCommand.php | 47 ++++++++-------------------------- 1 file changed, 10 insertions(+), 37 deletions(-) diff --git a/src/Commands/ImportCommand.php b/src/Commands/ImportCommand.php index 4238534..02b15b7 100644 --- a/src/Commands/ImportCommand.php +++ b/src/Commands/ImportCommand.php @@ -15,15 +15,15 @@ class ImportCommand extends Command * @var string */ protected $signature = 'langman:import - {filename? : Filename inside Langman CSV directory} - {--P|path= : The location where the CSV file is located.}'; + {filename? : Filename inside Langman Excel directory.} + {--P|path= : The path to Excel file relative to base path.}'; /** * The name and signature of the console command. * * @var string */ - protected $description = 'Generates a CSV file from your language files'; + protected $description = 'Generates your language files from an Excel file'; /** * The Languages manager instance. @@ -68,12 +68,12 @@ public function __construct(Manager $manager, Filesystem $filesystem) */ public function handle() { - $csvFileContents = $this->getCsvFileContents(); + $excelFileContents = $this->getExcelFileContents(); - $filesToBeChanged = join("\n\t", array_keys(array_first($csvFileContents))); + $filesToBeChanged = join("\n\t", array_keys(array_first($excelFileContents))); if (! $this->confirm("The following files will be overridden: \n\t" . $filesToBeChanged . "\nAre you sure?")) { - $this->line('No files changed.'); + $this->line('No files changed. Closing.'); exit(); } @@ -82,14 +82,14 @@ public function handle() $this->info('Import complete.'); } - protected function getCsvFileContents() + protected function getExcelFileContents() { if (is_null($this->option('path'))) { if (is_null($fileName = $this->argument('filename'))) { $this->error('No path specified.'); exit(); } else { - $filePath = config('langman.csv_path') .DIRECTORY_SEPARATOR. $fileName; + $filePath = config('langman.exports_path') .DIRECTORY_SEPARATOR. $fileName; } } else { $filePath = base_path($this->option('path')); @@ -100,39 +100,12 @@ protected function getCsvFileContents() exit(); } - return $this->readCsvFileContents($filePath); + return $this->readExcelFileContents($filePath); } - protected function readCsvFileContents($filePath) + protected function readExcelFileContents($filePath) { - $csv = array_map('str_getcsv', file($filePath)); - // Get header content - $langDirs = array_slice(array_shift($csv), 2); - - $groupedByDirName = []; - - foreach ($langDirs as $index => $langDir) { - $groupedByFileNames = []; - $trans = []; - $langDirName = ''; - foreach ($csv as $langRow) { - if ($langDirName != '' && $langDirName != $langRow[0]) { - $trans = []; - } - $langDirName = $langRow[0]; - $langKey = $langRow[1]; - - $langIndex = $index+2; - $trans[$langKey] = $langRow[$langIndex]; - - $groupedByFileNames[$langDirName] = $trans; - } - - $groupedByDirName[$langDir] = $groupedByFileNames; - } - - return $groupedByDirName; } protected function writeToLangFiles($data) From c110dc01f53dc8c9998a7d470d9b4ac50c262fde Mon Sep 17 00:00:00 2001 From: Mustafa Ehsan Alokozay Date: Thu, 11 Aug 2016 09:46:23 +0430 Subject: [PATCH 11/37] Temp commit --- src/Commands/ImportCommand.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Commands/ImportCommand.php b/src/Commands/ImportCommand.php index 02b15b7..59ac014 100644 --- a/src/Commands/ImportCommand.php +++ b/src/Commands/ImportCommand.php @@ -105,7 +105,13 @@ protected function getExcelFileContents() protected function readExcelFileContents($filePath) { + $excelObj = \PHPExcel_IOFactory::load($filePath); + $rows = $excelObj->getActiveSheet()->toArray('', true, true, true); + + foreach ($rows as $row) { + dd(array_values($row)); + } } protected function writeToLangFiles($data) From 9576921696d32413dc7ed94181f5a188594140e3 Mon Sep 17 00:00:00 2001 From: Mustafa Ehsan Alokozay Date: Thu, 11 Aug 2016 10:32:46 +0430 Subject: [PATCH 12/37] Complete import feature --- src/Commands/ImportCommand.php | 66 ++++++++++++++++++++++++++-------- 1 file changed, 52 insertions(+), 14 deletions(-) diff --git a/src/Commands/ImportCommand.php b/src/Commands/ImportCommand.php index 59ac014..d3d9833 100644 --- a/src/Commands/ImportCommand.php +++ b/src/Commands/ImportCommand.php @@ -77,23 +77,14 @@ public function handle() exit(); } - $this->writeToLangFiles($csvFileContents); + $this->writeToLangFiles($excelFileContents); $this->info('Import complete.'); } protected function getExcelFileContents() { - if (is_null($this->option('path'))) { - if (is_null($fileName = $this->argument('filename'))) { - $this->error('No path specified.'); - exit(); - } else { - $filePath = config('langman.exports_path') .DIRECTORY_SEPARATOR. $fileName; - } - } else { - $filePath = base_path($this->option('path')); - } + $filePath = $this->getPathFromUserArgs(); if (! file_exists($filePath)) { $this->error('No such file found: ' . $filePath); @@ -103,15 +94,62 @@ protected function getExcelFileContents() return $this->readExcelFileContents($filePath); } + protected function getPathFromUserArgs() + { + if (! is_null($fileName = $this->argument('filename'))) { + return config('langman.exports_path') . DIRECTORY_SEPARATOR . $fileName; + } + + if (is_null($this->option('path'))) { + $this->error('No path specified.'); + exit(); + } + + return base_path($this->option('path')); + } + protected function readExcelFileContents($filePath) { $excelObj = \PHPExcel_IOFactory::load($filePath); - $rows = $excelObj->getActiveSheet()->toArray('', true, true, true); - foreach ($rows as $row) { - dd(array_values($row)); + $langDirs = $this->extractLangages($rows); + + $groupedByDirName = []; + + foreach ($langDirs as $index => $langDir) { + $groupedByFileNames = []; + $trans = []; + $langDirName = ''; + + foreach ($rows as $langRow) { + // Override PHPExcel's column based key array into regular numbered key array + $langRow = array_values($langRow); + + if ($langDirName != '' && $langDirName != $langRow[0]) { + $trans = []; + } + + $langDirName = $langRow[0]; + $langKey = $langRow[1]; + + $langIndex = $index+2; + $trans[$langKey] = $langRow[$langIndex]; + + $groupedByFileNames[$langDirName] = $trans; + } + + $groupedByDirName[$langDir] = $groupedByFileNames; } + + return $groupedByDirName; + } + + protected function extractLangages($rows) + { + $headerRow = array_shift($rows); + + return array_values(array_slice($headerRow, 2)); } protected function writeToLangFiles($data) From 947ec6e86ada2e9134782b8dfa685ec90c106af0 Mon Sep 17 00:00:00 2001 From: Mustafa Ehsan Alokozay Date: Thu, 11 Aug 2016 12:41:27 +0430 Subject: [PATCH 13/37] Add comments --- src/Commands/ImportCommand.php | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/Commands/ImportCommand.php b/src/Commands/ImportCommand.php index d3d9833..cc66045 100644 --- a/src/Commands/ImportCommand.php +++ b/src/Commands/ImportCommand.php @@ -82,6 +82,11 @@ public function handle() $this->info('Import complete.'); } + /** + * Gets the user choosen excel file content. + * + * @return array + */ protected function getExcelFileContents() { $filePath = $this->getPathFromUserArgs(); @@ -94,6 +99,11 @@ protected function getExcelFileContents() return $this->readExcelFileContents($filePath); } + /** + * Gets file path from user passed argument and option. + * + * @return string + */ protected function getPathFromUserArgs() { if (! is_null($fileName = $this->argument('filename'))) { @@ -108,6 +118,13 @@ protected function getPathFromUserArgs() return base_path($this->option('path')); } + /** + * Reads the actual Excel file from the specified path and returns + * conent in an array grouped by directory and file names. + * + * @param string $filePath + * @return array + */ protected function readExcelFileContents($filePath) { $excelObj = \PHPExcel_IOFactory::load($filePath); @@ -145,6 +162,12 @@ protected function readExcelFileContents($filePath) return $groupedByDirName; } + /** + * Extract available language locales from file rows. + * + * @param array $rows + * @return array + */ protected function extractLangages($rows) { $headerRow = array_shift($rows); @@ -152,6 +175,12 @@ protected function extractLangages($rows) return array_values(array_slice($headerRow, 2)); } + /** + * Write the content to language files. + * + * @param array $data + * @return void + */ protected function writeToLangFiles($data) { foreach ($data as $langDirName => $langDirContent) { From 2b92097e3f6fac90a7730ffc36d2c0f4b7bd9e22 Mon Sep 17 00:00:00 2001 From: Mustafa Ehsan Alokozay Date: Thu, 11 Aug 2016 12:48:50 +0430 Subject: [PATCH 14/37] Change help for commands --- src/Commands/ExportCommand.php | 4 ++-- src/Commands/ImportCommand.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Commands/ExportCommand.php b/src/Commands/ExportCommand.php index e9af036..d108d9e 100644 --- a/src/Commands/ExportCommand.php +++ b/src/Commands/ExportCommand.php @@ -14,9 +14,9 @@ class ExportCommand extends Command * @var string */ protected $signature = 'langman:export - {--P|path= : The location where the exported file should be exported.} + {--P|path= : The location where the exported file should be saved (Default: storage/langman-exports).} {--only= : Specify the file(s) you want to export to Excel} - {--exclude= : File(s) you do not want to export to Excel}'; + {--exclude= : Specify the file(s) you do NOT want to export to Excel}'; /** * The name and signature of the console command. diff --git a/src/Commands/ImportCommand.php b/src/Commands/ImportCommand.php index cc66045..035037b 100644 --- a/src/Commands/ImportCommand.php +++ b/src/Commands/ImportCommand.php @@ -15,7 +15,7 @@ class ImportCommand extends Command * @var string */ protected $signature = 'langman:import - {filename? : Filename inside Langman Excel directory.} + {filename? : Filename inside Langman Exports directory (storage/langman-exports).} {--P|path= : The path to Excel file relative to base path.}'; /** From 09ebed4d84483ecfb02ccb6e8f5f0f591e6fc33a Mon Sep 17 00:00:00 2001 From: Mustafa Ehsan Alokozay Date: Thu, 11 Aug 2016 13:04:27 +0430 Subject: [PATCH 15/37] Pop header row from file contents --- src/Commands/ImportCommand.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Commands/ImportCommand.php b/src/Commands/ImportCommand.php index 035037b..a2dd9d0 100644 --- a/src/Commands/ImportCommand.php +++ b/src/Commands/ImportCommand.php @@ -130,7 +130,8 @@ protected function readExcelFileContents($filePath) $excelObj = \PHPExcel_IOFactory::load($filePath); $rows = $excelObj->getActiveSheet()->toArray('', true, true, true); - $langDirs = $this->extractLangages($rows); + $headerRow = array_shift($rows); + $langDirs = $this->extractLangages($headerRow); $groupedByDirName = []; @@ -168,11 +169,9 @@ protected function readExcelFileContents($filePath) * @param array $rows * @return array */ - protected function extractLangages($rows) + protected function extractLangages($header) { - $headerRow = array_shift($rows); - - return array_values(array_slice($headerRow, 2)); + return array_values(array_slice($header, 2)); } /** From d85df9b0bda5eacca5a24e5d1ebab2db8ea8a4ed Mon Sep 17 00:00:00 2001 From: Mustafa Ehsan Alokozay Date: Thu, 11 Aug 2016 13:17:24 +0430 Subject: [PATCH 16/37] Fix CS. --- src/Manager.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Manager.php b/src/Manager.php index 8b4201d..1476a11 100644 --- a/src/Manager.php +++ b/src/Manager.php @@ -81,8 +81,8 @@ public function files($fileNames = []) if (! Str::contains($this->path, 'vendor')) { $filesByFile = $this->neglectVendorFiles($filesByFile); } - - $fileNames = (array) $fileNames; + + $fileNames = (array) $fileNames; if (! empty($fileNames)) { return array_intersect_key($filesByFile, array_combine($fileNames, $fileNames)); @@ -401,7 +401,7 @@ public function getKeysExistingInALanguageButNotTheOther($values) */ public function getFilesContentGroupedByFilenameAndKey($selectedFiles = []) { - $files = $this->files((array) $selectedFiles); + $files = $this->files((array) $selectedFiles); $allLangs = []; $filesContent = []; From fabc62ce3958d5b1e88aeca3e9d3e6c9db8860c6 Mon Sep 17 00:00:00 2001 From: Mustafa Ehsan Alokozay Date: Thu, 11 Aug 2016 13:18:51 +0430 Subject: [PATCH 17/37] Fix CS --- src/Manager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Manager.php b/src/Manager.php index 1476a11..6cecc30 100644 --- a/src/Manager.php +++ b/src/Manager.php @@ -401,7 +401,7 @@ public function getKeysExistingInALanguageButNotTheOther($values) */ public function getFilesContentGroupedByFilenameAndKey($selectedFiles = []) { - $files = $this->files((array) $selectedFiles); + $files = $this->files((array) $selectedFiles); $allLangs = []; $filesContent = []; From 9d9edb80fca737aae4716d9426e619560ac7058a Mon Sep 17 00:00:00 2001 From: Mustafa Ehsan Alokozay Date: Thu, 11 Aug 2016 13:20:57 +0430 Subject: [PATCH 18/37] Fix CS --- src/Support/Arr.php | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/Support/Arr.php b/src/Support/Arr.php index db0e867..a979d71 100644 --- a/src/Support/Arr.php +++ b/src/Support/Arr.php @@ -3,12 +3,7 @@ namespace Themsaid\Langman\Support; use Illuminate\Support\Arr as BaseArr; -/** - * Created by PhpStorm. - * User: mustafaehsan - * Date: 6/11/16 - * Time: 9:10 PM - */ + class Arr extends BaseArr { /** @@ -40,4 +35,4 @@ public static function unDot($array, $recursively = true) return $results; } -} \ No newline at end of file +} From 7cf6923ab186d3a15f52fce4fc2603651ac44dfe Mon Sep 17 00:00:00 2001 From: Mustafa Ehsan Alokozay Date: Thu, 11 Aug 2016 13:23:20 +0430 Subject: [PATCH 19/37] Remove test temp files --- tests/temp/en/users.php | 7 ------- tests/temp/nl/users.php | 2 -- 2 files changed, 9 deletions(-) delete mode 100644 tests/temp/en/users.php delete mode 100644 tests/temp/nl/users.php diff --git a/tests/temp/en/users.php b/tests/temp/en/users.php deleted file mode 100644 index 8bf56f3..0000000 --- a/tests/temp/en/users.php +++ /dev/null @@ -1,7 +0,0 @@ - [ - 'first' => 'name', - ], -]; \ No newline at end of file diff --git a/tests/temp/nl/users.php b/tests/temp/nl/users.php deleted file mode 100644 index b2f4336..0000000 --- a/tests/temp/nl/users.php +++ /dev/null @@ -1,2 +0,0 @@ - Date: Thu, 11 Aug 2016 13:27:17 +0430 Subject: [PATCH 20/37] Fix CS --- tests/ManagerTest.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/ManagerTest.php b/tests/ManagerTest.php index 14cd012..729a3a3 100644 --- a/tests/ManagerTest.php +++ b/tests/ManagerTest.php @@ -34,16 +34,16 @@ public function testFilesMethod() // 'sp' => __DIR__.'/temp/vendor/package/sp/user.php', // ], ]; - - $expectedUserOnly = [ + + $expectedUserOnly = [ 'user' => [ 'en' => __DIR__.DIRECTORY_SEPARATOR.'temp'.DIRECTORY_SEPARATOR.'en'.DIRECTORY_SEPARATOR.'user.php', 'nl' => __DIR__.DIRECTORY_SEPARATOR.'temp'.DIRECTORY_SEPARATOR.'nl'.DIRECTORY_SEPARATOR.'user.php', ] - ]; + ]; $this->assertEquals($expected, $manager->files()); - $this->assertEquals($expectedUserOnly, $manager->files('user')); + $this->assertEquals($expectedUserOnly, $manager->files('user')); } public function testLanguagesMethod() @@ -316,8 +316,8 @@ public function testGetFilesContentGroupedByFilenameAndKeyMethod() ] ] ]; - - $expectedUserOnly = [ + + $expectedUserOnly = [ 'user' => [ 'missing.not_found' => [ 'key' => 'missing.not_found', @@ -335,8 +335,8 @@ public function testGetFilesContentGroupedByFilenameAndKeyMethod() $this->createTempFiles($filesList); $this->assertEquals($expected, $manager->getFilesContentGroupedByFilenameAndKey()); - $this->assertEquals($expected, $manager->getFilesContentGroupedByFilenameAndKey([])); + $this->assertEquals($expected, $manager->getFilesContentGroupedByFilenameAndKey([])); $this->assertEquals($expectedUserOnly, $manager->getFilesContentGroupedByFilenameAndKey(['user'])); - $this->assertEquals($expectedUserOnly, $manager->getFilesContentGroupedByFilenameAndKey('user')); + $this->assertEquals($expectedUserOnly, $manager->getFilesContentGroupedByFilenameAndKey('user')); } } From 2ecc03816ae27f8812b9f4136e43611fd37106cd Mon Sep 17 00:00:00 2001 From: Mustafa Ehsan Alokozay Date: Thu, 11 Aug 2016 13:30:48 +0430 Subject: [PATCH 21/37] Fix CS --- tests/ManagerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ManagerTest.php b/tests/ManagerTest.php index 729a3a3..53d14f9 100644 --- a/tests/ManagerTest.php +++ b/tests/ManagerTest.php @@ -330,7 +330,7 @@ public function testGetFilesContentGroupedByFilenameAndKeyMethod() 'fr' => 'French Edit User' ] ] - ]; + ]; $this->createTempFiles($filesList); From d420bea7064908afb4a3fcc0ad5a2f87a24be407 Mon Sep 17 00:00:00 2001 From: Mustafa Ehsan Alokozay Date: Thu, 11 Aug 2016 13:31:53 +0430 Subject: [PATCH 22/37] Fix CS --- tests/ManagerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ManagerTest.php b/tests/ManagerTest.php index 729a3a3..230b65a 100644 --- a/tests/ManagerTest.php +++ b/tests/ManagerTest.php @@ -330,7 +330,7 @@ public function testGetFilesContentGroupedByFilenameAndKeyMethod() 'fr' => 'French Edit User' ] ] - ]; + ]; $this->createTempFiles($filesList); From 17656ebf8183c26ecadcf5b6583497c207aea703 Mon Sep 17 00:00:00 2001 From: Mustafa Ehsan Alokozay Date: Thu, 11 Aug 2016 13:34:04 +0430 Subject: [PATCH 23/37] Fix CS --- tests/ManagerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ManagerTest.php b/tests/ManagerTest.php index 53d14f9..230b65a 100644 --- a/tests/ManagerTest.php +++ b/tests/ManagerTest.php @@ -330,7 +330,7 @@ public function testGetFilesContentGroupedByFilenameAndKeyMethod() 'fr' => 'French Edit User' ] ] - ]; + ]; $this->createTempFiles($filesList); From d6bdaa554412ee669d2d0c3188cc1a5c18f9b8b8 Mon Sep 17 00:00:00 2001 From: Mustafa Ehsan Alokozay Date: Thu, 11 Aug 2016 15:01:39 +0430 Subject: [PATCH 24/37] Add test temp folder --- tests/temp/en/users.php | 7 +++++++ tests/temp/nl/users.php | 2 ++ 2 files changed, 9 insertions(+) create mode 100644 tests/temp/en/users.php create mode 100644 tests/temp/nl/users.php diff --git a/tests/temp/en/users.php b/tests/temp/en/users.php new file mode 100644 index 0000000..8bf56f3 --- /dev/null +++ b/tests/temp/en/users.php @@ -0,0 +1,7 @@ + [ + 'first' => 'name', + ], +]; \ No newline at end of file diff --git a/tests/temp/nl/users.php b/tests/temp/nl/users.php new file mode 100644 index 0000000..b2f4336 --- /dev/null +++ b/tests/temp/nl/users.php @@ -0,0 +1,2 @@ + Date: Thu, 11 Aug 2016 15:03:16 +0430 Subject: [PATCH 25/37] Fix CS --- tests/temp/en/users.php | 10 +++++----- tests/temp/nl/users.php | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/temp/en/users.php b/tests/temp/en/users.php index 8bf56f3..0de4d83 100644 --- a/tests/temp/en/users.php +++ b/tests/temp/en/users.php @@ -1,7 +1,7 @@ - [ - 'first' => 'name', - ], -]; \ No newline at end of file + 'name' => [ + 'first' => 'name', + ], +]; diff --git a/tests/temp/nl/users.php b/tests/temp/nl/users.php index b2f4336..881ab67 100644 --- a/tests/temp/nl/users.php +++ b/tests/temp/nl/users.php @@ -1,2 +1,2 @@ Date: Fri, 9 Sep 2016 11:57:55 +0430 Subject: [PATCH 26/37] Remove comment from test --- tests/TestCase.php | 2 +- tests/temp/en/users.php | 7 ------- tests/temp/nl/users.php | 2 -- 3 files changed, 1 insertion(+), 10 deletions(-) delete mode 100644 tests/temp/en/users.php delete mode 100644 tests/temp/nl/users.php diff --git a/tests/TestCase.php b/tests/TestCase.php index f7844f8..9e94e0b 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -26,7 +26,7 @@ public function tearDown() { parent::tearDown(); -// exec('rm -rf '.__DIR__.'/temp/*'); + exec('rm -rf '.__DIR__.'/temp/*'); $this->consoleOutput = ''; } diff --git a/tests/temp/en/users.php b/tests/temp/en/users.php deleted file mode 100644 index 0de4d83..0000000 --- a/tests/temp/en/users.php +++ /dev/null @@ -1,7 +0,0 @@ - [ - 'first' => 'name', - ], -]; diff --git a/tests/temp/nl/users.php b/tests/temp/nl/users.php deleted file mode 100644 index 881ab67..0000000 --- a/tests/temp/nl/users.php +++ /dev/null @@ -1,2 +0,0 @@ - Date: Fri, 9 Sep 2016 19:17:38 +0430 Subject: [PATCH 27/37] Write initial tests for export command --- .gitignore | 1 + composer.json | 3 +- tests/ExportCommandTest.php | 67 +++++++++++++++++++++++++++++++++++++ tests/TestCase.php | 3 ++ 4 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 tests/ExportCommandTest.php diff --git a/.gitignore b/.gitignore index 2f87cd7..cd3b2f2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /vendor composer.phar composer.lock +.idea \ No newline at end of file diff --git a/composer.json b/composer.json index 2871bbe..660dacd 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,8 @@ "phpunit/phpunit" : "^4.8 || ^5.0", "orchestra/testbench": "3.3.x-dev", "orchestra/database": "3.3.x-dev", - "mockery/mockery": "~0.9.4" + "mockery/mockery": "~0.9.4", + "mikey179/vfsStream": "1.*" }, "autoload": { "psr-4": { diff --git a/tests/ExportCommandTest.php b/tests/ExportCommandTest.php new file mode 100644 index 0000000..5d59aab --- /dev/null +++ b/tests/ExportCommandTest.php @@ -0,0 +1,67 @@ +createTempFiles([ + 'en' => ['user' => " 'Address', 'contact' => ['cellphone' => 'Mobile']];"], + 'es' => ['user' => " 'Dirección', 'contact' => ['cellphone' => 'Movil']];"], + ]); + + $this->artisan('langman:export'); + + $exportedFilePath = $this->app['config']['langman.exports_path'] . '/' . date('Y_m_d_His') . '_langman.xlsx'; + + $excelRows = $this->getExcelFileContents($exportedFilePath); + + $headerRow = $excelRows[1]; + $contentRows = [$excelRows[2], $excelRows[3]]; + + $this->assertFileExists($exportedFilePath); + $this->assertHeaderRow($headerRow); + $this->assertContentRows($contentRows); + } + + /** + * @param $exportedFilePath + * @return array + */ + protected function getExcelFileContents($exportedFilePath) + { + $excelObj = \PHPExcel_IOFactory::load($exportedFilePath); + $rows = $excelObj->getActiveSheet()->toArray('', true, true, true); + + return $rows; + } + + /** + * @param $headerRow + */ + protected function assertHeaderRow($headerRow) + { + $this->assertEquals($headerRow['A'], 'Language File'); + $this->assertEquals($headerRow['B'], 'Key'); + $this->assertEquals($headerRow['C'], 'en'); + $this->assertEquals($headerRow['D'], 'es'); + } + + /** + * @param $row1 + * @param $row2 + */ + protected function assertContentRows($contentRows) + { + $row1 = $contentRows[0]; + $this->assertEquals($row1['A'], 'user'); + $this->assertEquals($row1['B'], 'address'); + $this->assertEquals($row1['C'], 'Address'); + $this->assertEquals($row1['D'], 'Dirección'); + + $row2 = $contentRows[1]; + $this->assertEquals($row2['A'], 'user'); + $this->assertEquals($row2['B'], 'contact.cellphone'); + $this->assertEquals($row2['C'], 'Mobile'); + $this->assertEquals($row2['D'], 'Movil'); + } +} \ No newline at end of file diff --git a/tests/TestCase.php b/tests/TestCase.php index 9e94e0b..382b938 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -12,6 +12,7 @@ protected function getPackageProviders($app) protected function getEnvironmentSetUp($app) { $app['config']->set('langman.path', __DIR__.'/temp'); + $app['config']->set('langman.exports_path', __DIR__.'/temp_exports_path'); $app['config']->set('view.paths', [__DIR__.'/views_temp']); } @@ -20,6 +21,7 @@ public function setUp() parent::setUp(); exec('rm -rf '.__DIR__.'/temp/*'); + exec('rm -rf '.__DIR__.'/temp_exports_path/*'); } public function tearDown() @@ -27,6 +29,7 @@ public function tearDown() parent::tearDown(); exec('rm -rf '.__DIR__.'/temp/*'); + exec('rm -rf '.__DIR__.'/temp_exports_path/*'); $this->consoleOutput = ''; } From 223665cd115882e122eb340f51bc410b58b35be4 Mon Sep 17 00:00:00 2001 From: Mustafa Ehsan Alokozay Date: Fri, 9 Sep 2016 19:26:26 +0430 Subject: [PATCH 28/37] Test cleanup --- .gitignore | 3 +-- composer.json | 3 +-- tests/ExportCommandTest.php | 11 ----------- 3 files changed, 2 insertions(+), 15 deletions(-) diff --git a/.gitignore b/.gitignore index cd3b2f2..0f550ff 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ /vendor composer.phar -composer.lock -.idea \ No newline at end of file +composer.lock \ No newline at end of file diff --git a/composer.json b/composer.json index 660dacd..2871bbe 100644 --- a/composer.json +++ b/composer.json @@ -22,8 +22,7 @@ "phpunit/phpunit" : "^4.8 || ^5.0", "orchestra/testbench": "3.3.x-dev", "orchestra/database": "3.3.x-dev", - "mockery/mockery": "~0.9.4", - "mikey179/vfsStream": "1.*" + "mockery/mockery": "~0.9.4" }, "autoload": { "psr-4": { diff --git a/tests/ExportCommandTest.php b/tests/ExportCommandTest.php index 5d59aab..e691e62 100644 --- a/tests/ExportCommandTest.php +++ b/tests/ExportCommandTest.php @@ -23,10 +23,6 @@ public function testCreatesExcelFile() $this->assertContentRows($contentRows); } - /** - * @param $exportedFilePath - * @return array - */ protected function getExcelFileContents($exportedFilePath) { $excelObj = \PHPExcel_IOFactory::load($exportedFilePath); @@ -35,9 +31,6 @@ protected function getExcelFileContents($exportedFilePath) return $rows; } - /** - * @param $headerRow - */ protected function assertHeaderRow($headerRow) { $this->assertEquals($headerRow['A'], 'Language File'); @@ -46,10 +39,6 @@ protected function assertHeaderRow($headerRow) $this->assertEquals($headerRow['D'], 'es'); } - /** - * @param $row1 - * @param $row2 - */ protected function assertContentRows($contentRows) { $row1 = $contentRows[0]; From 9b5c191cf6dc1f1864830a588545a722146c0cbe Mon Sep 17 00:00:00 2001 From: Mustafa Ehsan Alokozay Date: Sat, 10 Sep 2016 01:23:45 +0430 Subject: [PATCH 29/37] Refactor tests --- tests/ExportCommandTest.php | 35 ++++++++++------------------------- 1 file changed, 10 insertions(+), 25 deletions(-) diff --git a/tests/ExportCommandTest.php b/tests/ExportCommandTest.php index e691e62..cf7f714 100644 --- a/tests/ExportCommandTest.php +++ b/tests/ExportCommandTest.php @@ -15,12 +15,10 @@ public function testCreatesExcelFile() $excelRows = $this->getExcelFileContents($exportedFilePath); - $headerRow = $excelRows[1]; - $contentRows = [$excelRows[2], $excelRows[3]]; - $this->assertFileExists($exportedFilePath); - $this->assertHeaderRow($headerRow); - $this->assertContentRows($contentRows); + $this->assertExcelRowEquals($excelRows[1], ['Language File', 'Key', 'en', 'es']); + $this->assertExcelRowEquals($excelRows[2], ['user', 'address', 'Address', 'Dirección']); + $this->assertExcelRowEquals($excelRows[3], ['user', 'contact.cellphone', 'Mobile', 'Movil']); } protected function getExcelFileContents($exportedFilePath) @@ -31,26 +29,13 @@ protected function getExcelFileContents($exportedFilePath) return $rows; } - protected function assertHeaderRow($headerRow) - { - $this->assertEquals($headerRow['A'], 'Language File'); - $this->assertEquals($headerRow['B'], 'Key'); - $this->assertEquals($headerRow['C'], 'en'); - $this->assertEquals($headerRow['D'], 'es'); - } + protected function assertExcelRowEquals($row, $content) { + $columns = array_values($row); - protected function assertContentRows($contentRows) - { - $row1 = $contentRows[0]; - $this->assertEquals($row1['A'], 'user'); - $this->assertEquals($row1['B'], 'address'); - $this->assertEquals($row1['C'], 'Address'); - $this->assertEquals($row1['D'], 'Dirección'); - - $row2 = $contentRows[1]; - $this->assertEquals($row2['A'], 'user'); - $this->assertEquals($row2['B'], 'contact.cellphone'); - $this->assertEquals($row2['C'], 'Mobile'); - $this->assertEquals($row2['D'], 'Movil'); + $this->assertEquals(count($columns), count($content)); + + foreach ($columns as $index => $column) { + $this->assertEquals($column, $content[$index]); + } } } \ No newline at end of file From 554b929556337c8274a38bc14c6efc7274908b2c Mon Sep 17 00:00:00 2001 From: Mustafa Ehsan Alokozay Date: Sat, 10 Sep 2016 01:27:48 +0430 Subject: [PATCH 30/37] Add .gitignore back to temp folder --- tests/temp/.gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 tests/temp/.gitignore diff --git a/tests/temp/.gitignore b/tests/temp/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/tests/temp/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore From 4dfb81660addf5e088e508b45210bcd487f9a714 Mon Sep 17 00:00:00 2001 From: Mustafa Ehsan Alokozay Date: Sat, 10 Sep 2016 01:29:15 +0430 Subject: [PATCH 31/37] Checkout .gitignore to old version --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 0f550ff..2f87cd7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ /vendor composer.phar -composer.lock \ No newline at end of file +composer.lock From 0219786c36b38298ce93a7d0cc18596c7af6b3f9 Mon Sep 17 00:00:00 2001 From: Mustafa Ehsan Alokozay Date: Sat, 10 Sep 2016 09:55:32 +0430 Subject: [PATCH 32/37] Add tests for only option of export command --- tests/ExportCommandTest.php | 73 ++++++++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 2 deletions(-) diff --git a/tests/ExportCommandTest.php b/tests/ExportCommandTest.php index cf7f714..08f9392 100644 --- a/tests/ExportCommandTest.php +++ b/tests/ExportCommandTest.php @@ -2,7 +2,7 @@ class ExportCommandTest extends TestCase { - public function testCreatesExcelFile() + public function testCommandExportCreatesExcelFileFromLangFiles() { $this->createTempFiles([ 'en' => ['user' => " 'Address', 'contact' => ['cellphone' => 'Mobile']];"], @@ -11,7 +11,7 @@ public function testCreatesExcelFile() $this->artisan('langman:export'); - $exportedFilePath = $this->app['config']['langman.exports_path'] . '/' . date('Y_m_d_His') . '_langman.xlsx'; + $exportedFilePath = $this->getExportedFilePath(); $excelRows = $this->getExcelFileContents($exportedFilePath); @@ -21,6 +21,57 @@ public function testCreatesExcelFile() $this->assertExcelRowEquals($excelRows[3], ['user', 'contact.cellphone', 'Mobile', 'Movil']); } + public function testCommandExportOnlyExportsSpecifiedFiles() + { + $this->createTempFiles([ + 'en' => ['user' => " 'Address'];", 'course' => " 'Start Date'];",], + 'es' => ['user' => " 'Dirección'];", 'course' => " 'Fecha De Inicio'];"], + ]); + + $this->artisan('langman:export', ['--only' => 'course']); + + $exportedFilePath = $this->getExportedFilePath(); + + $excelRows = $this->getExcelFileContents($exportedFilePath); + + $this->assertFileExists($exportedFilePath); + + // Always remember that first row is the header row, + // it does not contain any language file content + $this->assertCount(2, $excelRows); + $this->assertTrue($this->excelContentContainsRow($excelRows, ['course', 'start_date', 'Start Date', 'Fecha De Inicio'])); + $this->assertFalse($this->excelContentContainsRow($excelRows, ['user', 'address', 'Address', 'Dirección'])); + } + + public function testOnlyOptionSupportsCommaSeparatedNames() + { + $this->createTempFiles([ + 'en' => [ + 'user' => " 'Address'];", + 'course' => " 'Start Date'];", + 'product' => " 'Name', 'description' => 'Description'];" + ], + 'es' => [ + 'user' => " 'Dirección'];", + 'course' => " 'Fecha De Inicio'];", + 'product' => " 'Nombre', 'description' => 'Descripción'];" + ], + ]); + + $this->artisan('langman:export', ['--only' => 'user,product']); + + $exportedFilePath = $this->getExportedFilePath(); + + $excelRows = $this->getExcelFileContents($exportedFilePath); + + $this->assertFileExists($exportedFilePath); + $this->assertCount(4, $excelRows); + $this->assertTrue($this->excelContentContainsRow($excelRows, ['user', 'address', 'Address', 'Dirección'])); + $this->assertTrue($this->excelContentContainsRow($excelRows, ['product', 'name', 'Name', 'Nombre'])); + $this->assertTrue($this->excelContentContainsRow($excelRows, ['product', 'description', 'Description', 'Descripción'])); + $this->assertFalse($this->excelContentContainsRow($excelRows, ['course', 'start_date', 'Start Date', 'Fecha De Inicio'])); + } + protected function getExcelFileContents($exportedFilePath) { $excelObj = \PHPExcel_IOFactory::load($exportedFilePath); @@ -38,4 +89,22 @@ protected function assertExcelRowEquals($row, $content) { $this->assertEquals($column, $content[$index]); } } + + protected function getExportedFilePath() + { + return $this->app['config']['langman.exports_path'] . '/' . date('Y_m_d_His') . '_langman.xlsx'; + } + + protected function excelContentContainsRow($excelRows, $row) + { + foreach ($excelRows as $excelRow) { + $excelRow = array_values($excelRow); + + if ($excelRow == $row) { + return true; + } + } + + return false; + } } \ No newline at end of file From 63392d8ab4c86d1a0023fea9ba12c304afc81e96 Mon Sep 17 00:00:00 2001 From: Mustafa Ehsan Alokozay Date: Sat, 10 Sep 2016 10:01:04 +0430 Subject: [PATCH 33/37] Complete tests for export command --- tests/ExportCommandTest.php | 53 ++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/tests/ExportCommandTest.php b/tests/ExportCommandTest.php index 08f9392..ce5bcfc 100644 --- a/tests/ExportCommandTest.php +++ b/tests/ExportCommandTest.php @@ -43,7 +43,7 @@ public function testCommandExportOnlyExportsSpecifiedFiles() $this->assertFalse($this->excelContentContainsRow($excelRows, ['user', 'address', 'Address', 'Dirección'])); } - public function testOnlyOptionSupportsCommaSeparatedNames() + public function testOptionOnlySupportsCommaSeparatedNames() { $this->createTempFiles([ 'en' => [ @@ -72,6 +72,57 @@ public function testOnlyOptionSupportsCommaSeparatedNames() $this->assertFalse($this->excelContentContainsRow($excelRows, ['course', 'start_date', 'Start Date', 'Fecha De Inicio'])); } + public function testCommandExportExcludesSpecifiedFiles() + { + $this->createTempFiles([ + 'en' => ['user' => " 'Address'];", 'course' => " 'Start Date'];",], + 'es' => ['user' => " 'Dirección'];", 'course' => " 'Fecha De Inicio'];"], + ]); + + $this->artisan('langman:export', ['--exclude' => 'user']); + + $exportedFilePath = $this->getExportedFilePath(); + + $excelRows = $this->getExcelFileContents($exportedFilePath); + + $this->assertFileExists($exportedFilePath); + + // Always remember that first row is the header row, + // it does not contain any language file content + $this->assertCount(2, $excelRows); + $this->assertTrue($this->excelContentContainsRow($excelRows, ['course', 'start_date', 'Start Date', 'Fecha De Inicio'])); + $this->assertFalse($this->excelContentContainsRow($excelRows, ['user', 'address', 'Address', 'Dirección'])); + } + + public function testOptionExcludeSupportsCommaSeparatedNames() + { + $this->createTempFiles([ + 'en' => [ + 'user' => " 'Address'];", + 'course' => " 'Start Date'];", + 'product' => " 'Name', 'description' => 'Description'];" + ], + 'es' => [ + 'user' => " 'Dirección'];", + 'course' => " 'Fecha De Inicio'];", + 'product' => " 'Nombre', 'description' => 'Descripción'];" + ], + ]); + + $this->artisan('langman:export', ['--exclude' => 'user,product']); + + $exportedFilePath = $this->getExportedFilePath(); + + $excelRows = $this->getExcelFileContents($exportedFilePath); + + $this->assertFileExists($exportedFilePath); + $this->assertCount(2, $excelRows); + $this->assertFalse($this->excelContentContainsRow($excelRows, ['user', 'address', 'Address', 'Dirección'])); + $this->assertFalse($this->excelContentContainsRow($excelRows, ['product', 'name', 'Name', 'Nombre'])); + $this->assertFalse($this->excelContentContainsRow($excelRows, ['product', 'description', 'Description', 'Descripción'])); + $this->assertTrue($this->excelContentContainsRow($excelRows, ['course', 'start_date', 'Start Date', 'Fecha De Inicio'])); + } + protected function getExcelFileContents($exportedFilePath) { $excelObj = \PHPExcel_IOFactory::load($exportedFilePath); From b514f1a4ba4c9ea4aa0f083ca4196da8ae22d8e2 Mon Sep 17 00:00:00 2001 From: Mustafa Ehsan Alokozay Date: Sat, 10 Sep 2016 10:19:06 +0430 Subject: [PATCH 34/37] Test for combining exclude and only option of export command --- src/Commands/ExportCommand.php | 2 +- tests/ExportCommandTest.php | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/Commands/ExportCommand.php b/src/Commands/ExportCommand.php index d108d9e..5334660 100644 --- a/src/Commands/ExportCommand.php +++ b/src/Commands/ExportCommand.php @@ -92,7 +92,7 @@ protected function filterFilesForExport() { if (! is_null($this->option('only')) && ! is_null($this->option('exclude'))) { $this->error('You cannot combine --only and --exclude options. Please use one of them.'); - exit(); + return; } $onlyFiles = []; diff --git a/tests/ExportCommandTest.php b/tests/ExportCommandTest.php index ce5bcfc..886c801 100644 --- a/tests/ExportCommandTest.php +++ b/tests/ExportCommandTest.php @@ -87,8 +87,6 @@ public function testCommandExportExcludesSpecifiedFiles() $this->assertFileExists($exportedFilePath); - // Always remember that first row is the header row, - // it does not contain any language file content $this->assertCount(2, $excelRows); $this->assertTrue($this->excelContentContainsRow($excelRows, ['course', 'start_date', 'Start Date', 'Fecha De Inicio'])); $this->assertFalse($this->excelContentContainsRow($excelRows, ['user', 'address', 'Address', 'Dirección'])); @@ -123,6 +121,13 @@ public function testOptionExcludeSupportsCommaSeparatedNames() $this->assertTrue($this->excelContentContainsRow($excelRows, ['course', 'start_date', 'Start Date', 'Fecha De Inicio'])); } + public function testExcludeAndOnlyOptionCannotBeCombined() + { + $this->artisan('langman:export', ['--exclude' => 'somefile', '--only' => 'someanotherfile']); + + $this->assertContains('You cannot combine --only and --exclude options.', $this->consoleOutput()); + } + protected function getExcelFileContents($exportedFilePath) { $excelObj = \PHPExcel_IOFactory::load($exportedFilePath); From e4640b2d484baf10cba7c92ced404e964e8d249e Mon Sep 17 00:00:00 2001 From: Mustafa Ehsan Alokozay Date: Sat, 10 Sep 2016 11:55:23 +0430 Subject: [PATCH 35/37] Initial import command tests --- src/Commands/ImportCommand.php | 18 +++------- tests/ImportCommandTest.php | 61 ++++++++++++++++++++++++++++++++ tests/TestCase.php | 6 ++-- tests/temp_excel_path/.gitignore | 2 ++ 4 files changed, 70 insertions(+), 17 deletions(-) create mode 100644 tests/ImportCommandTest.php create mode 100644 tests/temp_excel_path/.gitignore diff --git a/src/Commands/ImportCommand.php b/src/Commands/ImportCommand.php index a2dd9d0..750cd60 100644 --- a/src/Commands/ImportCommand.php +++ b/src/Commands/ImportCommand.php @@ -3,7 +3,6 @@ namespace Themsaid\Langman\Commands; use Illuminate\Console\Command; -use Illuminate\Contracts\Filesystem\Filesystem; use Themsaid\Langman\Manager; use Themsaid\Langman\Support\Arr; @@ -32,13 +31,6 @@ class ImportCommand extends Command */ private $manager; - /** - * The Languages manager instance. - * - * @var \Illuminate\Contracts\Filesystem\Filesystem - */ - protected $filesystem; - /** * Array of files grouped by filename. * @@ -50,15 +42,13 @@ class ImportCommand extends Command * ListCommand constructor. * * @param \Themsaid\LangMan\Manager $manager - * @param \Illuminate\Contracts\Filesystem\Filesystem * @return void */ - public function __construct(Manager $manager, Filesystem $filesystem) + public function __construct(Manager $manager) { parent::__construct(); $this->manager = $manager; - $this->filesystem = $filesystem; } /** @@ -74,7 +64,7 @@ public function handle() if (! $this->confirm("The following files will be overridden: \n\t" . $filesToBeChanged . "\nAre you sure?")) { $this->line('No files changed. Closing.'); - exit(); + return; } $this->writeToLangFiles($excelFileContents); @@ -185,8 +175,8 @@ protected function writeToLangFiles($data) foreach ($data as $langDirName => $langDirContent) { $langDirPath = config('langman.path') . DIRECTORY_SEPARATOR . $langDirName; - if (! $this->filesystem->exists($langDirPath)) { - $this->filesystem->makeDirectory($langDirPath); + if (! file_exists($langDirPath)) { + mkdir($langDirPath); } foreach ($langDirContent as $fileName => $fileContent) { diff --git a/tests/ImportCommandTest.php b/tests/ImportCommandTest.php new file mode 100644 index 0000000..ffdb56d --- /dev/null +++ b/tests/ImportCommandTest.php @@ -0,0 +1,61 @@ +app[Manager::class]; + + $path = $this->createTempExcelFile([ + ['Language File', 'Key', 'en', 'es'], + ['product', 'name', 'Name', 'Nombre'], + ['product', 'description', 'Description', 'Descripción'], + ['course', 'start_date', 'Start Date', 'Fecha De Inicio'], + ['user', 'address', 'Address', 'Dirección'], + ['user', 'education.major', 'Major', 'Importante'], + ['user', 'education.minor', 'Minor', 'Menor'] + ]); + + $filename = basename($path); + + $filesToBeChanged = join("\n\t", ['product', 'course', 'user']); + + $command = m::mock('\Themsaid\Langman\Commands\ImportCommand[confirm]', [$manager]); + $command->shouldReceive('confirm')->once() + ->with("The following files will be overridden: \n\t" . $filesToBeChanged . "\nAre you sure?")->andReturn(true); + + $this->app['artisan']->add($command); + $this->artisan('langman:import', ['filename' => $filename]); + + $langPath = $this->app['config']['langman.path']; + + $this->assertFileExists($langPath . '/en/product.php'); + $this->assertFileExists($langPath . '/en/course.php'); + $this->assertFileExists($langPath . '/en/user.php'); + $this->assertFileExists($langPath . '/es/product.php'); + $this->assertFileExists($langPath . '/es/course.php'); + $this->assertFileExists($langPath . '/es/user.php'); + } + + /** + * Create a temporary excel file. + * + * @param $contentArray + * @return string + */ + protected function createTempExcelFile($contentArray) + { + $excelObj = new PHPExcel(); + + $excelObj->getActiveSheet()->fromArray($contentArray, ''); + + $objWriter = PHPExcel_IOFactory::createWriter($excelObj, 'Excel2007'); + $filePath = $this->app['config']['langman.exports_path'] . '/translations.xlsx'; + $objWriter->save($filePath); + + return $filePath; + } +} \ No newline at end of file diff --git a/tests/TestCase.php b/tests/TestCase.php index 382b938..91db137 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -12,7 +12,7 @@ protected function getPackageProviders($app) protected function getEnvironmentSetUp($app) { $app['config']->set('langman.path', __DIR__.'/temp'); - $app['config']->set('langman.exports_path', __DIR__.'/temp_exports_path'); + $app['config']->set('langman.exports_path', __DIR__.'/temp_excel_path'); $app['config']->set('view.paths', [__DIR__.'/views_temp']); } @@ -21,7 +21,7 @@ public function setUp() parent::setUp(); exec('rm -rf '.__DIR__.'/temp/*'); - exec('rm -rf '.__DIR__.'/temp_exports_path/*'); + exec('rm -rf '.__DIR__.'/temp_excel_path/*'); } public function tearDown() @@ -29,7 +29,7 @@ public function tearDown() parent::tearDown(); exec('rm -rf '.__DIR__.'/temp/*'); - exec('rm -rf '.__DIR__.'/temp_exports_path/*'); + exec('rm -rf '.__DIR__.'/temp_excel_path/*'); $this->consoleOutput = ''; } diff --git a/tests/temp_excel_path/.gitignore b/tests/temp_excel_path/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/tests/temp_excel_path/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore From ffdacfe06a3d7a255175d941b424a6fbaf6c9024 Mon Sep 17 00:00:00 2001 From: Mustafa Ehsan Alokozay Date: Sat, 10 Sep 2016 22:25:56 +0430 Subject: [PATCH 36/37] Complete import command tests --- src/Commands/ImportCommand.php | 10 ++++++--- tests/ImportCommandTest.php | 37 +++++++++++++++++++++++++--------- tests/TestCase.php | 2 +- 3 files changed, 36 insertions(+), 13 deletions(-) diff --git a/src/Commands/ImportCommand.php b/src/Commands/ImportCommand.php index 750cd60..04456d5 100644 --- a/src/Commands/ImportCommand.php +++ b/src/Commands/ImportCommand.php @@ -60,6 +60,11 @@ public function handle() { $excelFileContents = $this->getExcelFileContents(); + if (is_null($excelFileContents)) { + $this->error('No such file found.'); + return; + } + $filesToBeChanged = join("\n\t", array_keys(array_first($excelFileContents))); if (! $this->confirm("The following files will be overridden: \n\t" . $filesToBeChanged . "\nAre you sure?")) { @@ -73,7 +78,7 @@ public function handle() } /** - * Gets the user choosen excel file content. + * Gets the user chosen excel file content. * * @return array */ @@ -82,8 +87,7 @@ protected function getExcelFileContents() $filePath = $this->getPathFromUserArgs(); if (! file_exists($filePath)) { - $this->error('No such file found: ' . $filePath); - exit(); + return null; } return $this->readExcelFileContents($filePath); diff --git a/tests/ImportCommandTest.php b/tests/ImportCommandTest.php index ffdb56d..e37d827 100644 --- a/tests/ImportCommandTest.php +++ b/tests/ImportCommandTest.php @@ -11,8 +11,6 @@ public function testCommandImportsContentFromExcelToLangFiles() $path = $this->createTempExcelFile([ ['Language File', 'Key', 'en', 'es'], - ['product', 'name', 'Name', 'Nombre'], - ['product', 'description', 'Description', 'Descripción'], ['course', 'start_date', 'Start Date', 'Fecha De Inicio'], ['user', 'address', 'Address', 'Dirección'], ['user', 'education.major', 'Major', 'Importante'], @@ -21,7 +19,7 @@ public function testCommandImportsContentFromExcelToLangFiles() $filename = basename($path); - $filesToBeChanged = join("\n\t", ['product', 'course', 'user']); + $filesToBeChanged = join("\n\t", ['course', 'user']); $command = m::mock('\Themsaid\Langman\Commands\ImportCommand[confirm]', [$manager]); $command->shouldReceive('confirm')->once() @@ -32,12 +30,33 @@ public function testCommandImportsContentFromExcelToLangFiles() $langPath = $this->app['config']['langman.path']; - $this->assertFileExists($langPath . '/en/product.php'); - $this->assertFileExists($langPath . '/en/course.php'); - $this->assertFileExists($langPath . '/en/user.php'); - $this->assertFileExists($langPath . '/es/product.php'); - $this->assertFileExists($langPath . '/es/course.php'); - $this->assertFileExists($langPath . '/es/user.php'); + $userEnglish = include $langPath . '/en/user.php'; + $userSpanish = include $langPath . '/es/user.php'; + $courseEnglish = include $langPath . '/en/course.php'; + $courseSpanish = include $langPath . '/es/course.php'; + + $this->assertContains('Import complete', $this->consoleOutput()); + + // Assert user.php content + $this->assertEquals($userEnglish['address'], 'Address'); + $this->assertEquals($userSpanish['address'], 'Dirección'); + + // Assert dotted keys + $this->assertEquals($userEnglish['education']['major'], 'Major'); + $this->assertEquals($userEnglish['education']['minor'], 'Minor'); + $this->assertEquals($userSpanish['education']['major'], 'Importante'); + $this->assertEquals($userSpanish['education']['minor'], 'Menor'); + + // Assert course.php content + $this->assertEquals($courseEnglish['start_date'], 'Start Date'); + $this->assertEquals($courseSpanish['start_date'], 'Fecha De Inicio'); + } + + public function testCommandShowsErrorIfFileNotFound() + { + $this->artisan('langman:import', ['filename' => 'nofile.xlsx']); + + $this->assertContains('No such file found', $this->consoleOutput()); } /** diff --git a/tests/TestCase.php b/tests/TestCase.php index 91db137..4d20361 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -19,7 +19,7 @@ protected function getEnvironmentSetUp($app) public function setUp() { parent::setUp(); - + exec('rm -rf '.__DIR__.'/temp/*'); exec('rm -rf '.__DIR__.'/temp_excel_path/*'); } From b237efe764944b5bba9debbd73f530cd7f0b920f Mon Sep 17 00:00:00 2001 From: Mustafa Ehsan Alokozay Date: Sat, 10 Sep 2016 22:29:37 +0430 Subject: [PATCH 37/37] Fix CS --- tests/ExportCommandTest.php | 5 +++-- tests/ImportCommandTest.php | 2 +- tests/TestCase.php | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/ExportCommandTest.php b/tests/ExportCommandTest.php index 886c801..1a796ab 100644 --- a/tests/ExportCommandTest.php +++ b/tests/ExportCommandTest.php @@ -136,7 +136,8 @@ protected function getExcelFileContents($exportedFilePath) return $rows; } - protected function assertExcelRowEquals($row, $content) { + protected function assertExcelRowEquals($row, $content) + { $columns = array_values($row); $this->assertEquals(count($columns), count($content)); @@ -163,4 +164,4 @@ protected function excelContentContainsRow($excelRows, $row) return false; } -} \ No newline at end of file +} diff --git a/tests/ImportCommandTest.php b/tests/ImportCommandTest.php index e37d827..6ed9d83 100644 --- a/tests/ImportCommandTest.php +++ b/tests/ImportCommandTest.php @@ -77,4 +77,4 @@ protected function createTempExcelFile($contentArray) return $filePath; } -} \ No newline at end of file +} diff --git a/tests/TestCase.php b/tests/TestCase.php index 4d20361..91db137 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -19,7 +19,7 @@ protected function getEnvironmentSetUp($app) public function setUp() { parent::setUp(); - + exec('rm -rf '.__DIR__.'/temp/*'); exec('rm -rf '.__DIR__.'/temp_excel_path/*'); }