From ed1e5a26d0766c49aa12da85e7915c94a4e21cdb Mon Sep 17 00:00:00 2001 From: rahul Date: Wed, 20 Sep 2023 01:27:23 +0530 Subject: [PATCH] hide column feature Signed-off-by: rahul --- bin/view-csv | 23 ++++++++------- src/CsvFileHandler.php | 46 +++++++++++++++++++++++++++--- tests/unit/CsvFileHandlerTest.php | 47 +++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+), 14 deletions(-) diff --git a/bin/view-csv b/bin/view-csv index f63d577..8ac58db 100755 --- a/bin/view-csv +++ b/bin/view-csv @@ -5,19 +5,25 @@ require 'vendor/autoload.php'; use rcsofttech85\FileHandler\CsvFileHandler; use rcsofttech85\FileHandler\DI\ServiceContainer; +use rcsofttech85\FileHandler\Exception\FileHandlerException; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\SingleCommandApplication; use Symfony\Component\Console\Style\SymfonyStyle; $command = (new SingleCommandApplication()) ->addArgument('csvFile', InputArgument::REQUIRED, 'csv file name') + ->addOption('hide-column', null, InputOption::VALUE_REQUIRED, 'Columns to hide (comma-separated)') ->setCode(function (InputInterface $input, OutputInterface $output): int { $io = new SymfonyStyle($input, $output); $csvFile = $input->getArgument('csvFile'); + $hiddenColumns = $input->getOption('hide-column'); + + $hiddenColumnsArray = explode(',', $hiddenColumns); if (!file_exists($csvFile)) { $io->error("{$csvFile} does not exists"); @@ -28,23 +34,20 @@ $command = (new SingleCommandApplication()) /** @var CsvFileHandler $csvFileHandler */ $csvFileHandler = $serviceContainer->getContainerBuilder()->get('csv_file_handler'); - $io->title($csvFile); - $table = $io->createTable(); - $headers = $csvFileHandler->extractHeader($csvFile); - - if (!$headers) { + try { + $data = $csvFileHandler->toArray($csvFile, $hiddenColumnsArray); + } catch (FileHandlerException) { $io->error('invalid csv file'); return Command::FAILURE; } - + $headers = array_keys($data[0]); + $io->title($csvFile); + $table = $io->createTable(); $table->setHeaders($headers); - $table->setRows($csvFileHandler->toArray($csvFile)); - + $table->setRows($data); $table->render(); - $io->newLine(); - return Command::SUCCESS; })->run(); diff --git a/src/CsvFileHandler.php b/src/CsvFileHandler.php index 8928637..10a956b 100644 --- a/src/CsvFileHandler.php +++ b/src/CsvFileHandler.php @@ -49,16 +49,17 @@ public function toJson(string $filename): string|false /** * @param string $filename + * @param array $hideColumns * @return array> * @throws FileHandlerException */ - public function toArray(string $filename): array + public function toArray(string $filename, array|false $hideColumns = false): array { if (!file_exists($filename)) { throw new FileHandlerException('file not found'); } - return iterator_to_array($this->getRows($filename)); + return iterator_to_array($this->getRows($filename, $hideColumns)); } public function findAndReplaceInCsv( @@ -107,7 +108,7 @@ public function findAndReplaceInCsv( * @return array|false */ - public function extractHeader(mixed $file): array|false + private function extractHeader(mixed $file): array|false { $headers = []; if (is_resource($file)) { @@ -146,12 +147,34 @@ private function isValidCsvFileFormat(array $row): bool return true; } + /** + * @param array $row + * @param array $hideColumns + * @return array,int|string> + */ + private function setColumnsToHide(array &$row, array $hideColumns): array + { + $indices = []; + if (!empty($hideColumns)) { + foreach ($hideColumns as $hideColumn) { + $index = array_search($hideColumn, $row); + if ($index !== false) { + $indices[] = $index; + unset($row[$index]); + } + } + $row = array_values($row); + } + return $indices; + } + /** * @param string $filename + * @param array|false $hideColumns * @return Generator * @throws FileHandlerException */ - private function getRows(string $filename): Generator + private function getRows(string $filename, array|false $hideColumns = false): Generator { $csvFile = fopen($filename, 'r'); if (!$csvFile) { @@ -162,6 +185,10 @@ private function getRows(string $filename): Generator throw new FileHandlerException('could not extract header'); } + if (is_array($hideColumns)) { + $indices = $this->setColumnsToHide($headers, $hideColumns); + } + $isEmptyFile = true; try { @@ -170,6 +197,17 @@ private function getRows(string $filename): Generator if (!$this->isValidCsvFileFormat($row)) { throw new FileHandlerException('invalid csv file format'); } + + if (!empty($indices)) { + foreach ($indices as $index) { + if (isset($row[$index])) { + unset($row[$index]); + } + } + + $row = array_values($row); + } + $item = array_combine($headers, $row); yield $item; diff --git a/tests/unit/CsvFileHandlerTest.php b/tests/unit/CsvFileHandlerTest.php index edb5b18..485a215 100644 --- a/tests/unit/CsvFileHandlerTest.php +++ b/tests/unit/CsvFileHandlerTest.php @@ -111,6 +111,20 @@ public function toArrayMethodReturnsValidArray(): void $this->assertEquals($expected, $data[0]); } + /** + * @param array $columnsToHide + * @param array $expected + * @return void + * @throws FileHandlerException + */ + #[Test] + #[DataProvider('columnsToHideDataProvider')] + public function toArrayMethodWithHideColumnsOptionReturnsValidArray(array $columnsToHide, array $expected): void + { + $data = $this->csvFileHandler->toArray("movie.csv", $columnsToHide); + $this->assertEquals($expected, $data[0]); + } + #[Test] public function searchByKeywordAndReturnArray(): void { @@ -220,4 +234,37 @@ public static function wrongColumnNameProvider(): iterable yield ["wrong"]; yield ["honey bee"]; } + + /** + * @return iterable>> + */ + public static function columnsToHideDataProvider(): iterable + { + $hideSingleColumn = ["Film"]; + $expected1 = [ + 'Genre' => 'Romance', + 'Lead Studio' => 'The Weinstein Company', + 'Audience score %' => '70', + 'Profitability' => '1.747541667', + 'Rotten Tomatoes %' => '64', + 'Worldwide Gross' => '$41.94 ', + 'Year' => '2008' + + ]; + + $hideMultipleColumns = ["Film", "Profitability", "Year"]; + $expected2 = [ + 'Genre' => 'Romance', + 'Lead Studio' => 'The Weinstein Company', + 'Audience score %' => '70', + 'Rotten Tomatoes %' => '64', + 'Worldwide Gross' => '$41.94 ', + + + ]; + + + yield [$hideSingleColumn, $expected1]; + yield [$hideMultipleColumns, $expected2]; + } }