From bb04b27b2763aae79a86dc8bea789ce9e6633e84 Mon Sep 17 00:00:00 2001 From: Antoine Guigan Date: Fri, 6 Jun 2014 19:17:27 +0200 Subject: [PATCH 01/22] Modified WorkBookInterface to add options for iterator creation --- .gitignore | 2 +- .../Xlsx/RowIteratorFactorySpec.php | 11 +++++++++-- .../SpreadsheetParser/Xlsx/RowIteratorSpec.php | 3 ++- .../SpreadsheetParser/Xlsx/WorkbookSpec.php | 4 ++-- src/WorkbookInterface.php | 5 +++-- src/Xlsx/RowIterator.php | 18 ++++++++++++++---- src/Xlsx/RowIteratorFactory.php | 11 +++++++++-- src/Xlsx/Workbook.php | 9 ++++++--- 8 files changed, 46 insertions(+), 17 deletions(-) diff --git a/.gitignore b/.gitignore index 1b97d31..fc0124f 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,4 @@ vendor composer.lock phpunit.xml ~$*.xlsx - +/nbproject diff --git a/spec/Akeneo/Component/SpreadsheetParser/Xlsx/RowIteratorFactorySpec.php b/spec/Akeneo/Component/SpreadsheetParser/Xlsx/RowIteratorFactorySpec.php index 4130bf5..f09628f 100644 --- a/spec/Akeneo/Component/SpreadsheetParser/Xlsx/RowIteratorFactorySpec.php +++ b/spec/Akeneo/Component/SpreadsheetParser/Xlsx/RowIteratorFactorySpec.php @@ -28,8 +28,9 @@ public function it_creates_row_iterators( ColumnIndexTransformer $columnIndexTransformer, ValueTransformer $valueTransformer ) { - $iterator = $this->create($valueTransformer, 'path'); + $iterator = $this->create($valueTransformer, 'path', ['options']); $iterator->getPath()->shouldReturn('path'); + $iterator->getOptions()->shouldReturn(['options']); $iterator->getValueTransformer()->shouldReturn($valueTransformer); $iterator->getRowBuilderFactory()->shouldReturn($rowBuilderFactory); $iterator->getColumnIndexTransformer()->shouldReturn($columnIndexTransformer); @@ -42,12 +43,14 @@ class StubRowIterator protected $columnIndexTransformer; protected $valueTransformer; protected $path; - public function __construct($rowBuilderFactory, $columnIndexTransformer, $valueTransformer, $path) + protected $options; + public function __construct($rowBuilderFactory, $columnIndexTransformer, $valueTransformer, $path, $options) { $this->rowBuilderFactory = $rowBuilderFactory; $this->columnIndexTransformer = $columnIndexTransformer; $this->valueTransformer = $valueTransformer; $this->path = $path; + $this->options = $options; } public function getPath() { @@ -65,4 +68,8 @@ public function getColumnIndexTransformer() { return $this->columnIndexTransformer; } + public function getOptions() + { + return $this->options; + } } diff --git a/spec/Akeneo/Component/SpreadsheetParser/Xlsx/RowIteratorSpec.php b/spec/Akeneo/Component/SpreadsheetParser/Xlsx/RowIteratorSpec.php index adc3434..346c82b 100644 --- a/spec/Akeneo/Component/SpreadsheetParser/Xlsx/RowIteratorSpec.php +++ b/spec/Akeneo/Component/SpreadsheetParser/Xlsx/RowIteratorSpec.php @@ -50,7 +50,8 @@ function () use (&$row) { $rowBuilderFactory, $columnIndexTransformer, $valueTransformer, - __DIR__ . '/../fixtures/sheet.xml' + __DIR__ . '/../fixtures/sheet.xml', + [] ); $valueTransformer->transform(Argument::type('string'),Argument::type('string'),Argument::type('string'))->will( function ($args) { diff --git a/spec/Akeneo/Component/SpreadsheetParser/Xlsx/WorkbookSpec.php b/spec/Akeneo/Component/SpreadsheetParser/Xlsx/WorkbookSpec.php index 1bdadf6..45f518c 100644 --- a/spec/Akeneo/Component/SpreadsheetParser/Xlsx/WorkbookSpec.php +++ b/spec/Akeneo/Component/SpreadsheetParser/Xlsx/WorkbookSpec.php @@ -93,8 +93,8 @@ public function it_creates_row_iterators( RowIterator $rowIterator1, RowIterator $rowIterator2 ) { - $rowIteratorFactory->create($valueTransformer, 'temp_path1')->willReturn($rowIterator1); - $rowIteratorFactory->create($valueTransformer, 'temp_path2')->willReturn($rowIterator2); + $rowIteratorFactory->create($valueTransformer, 'temp_path1', [])->willReturn($rowIterator1); + $rowIteratorFactory->create($valueTransformer, 'temp_path2', [])->willReturn($rowIterator2); $this->createRowIterator(0)->shouldReturn($rowIterator1); $this->createRowIterator(1)->shouldReturn($rowIterator2); diff --git a/src/WorkbookInterface.php b/src/WorkbookInterface.php index b7aaa00..88de05c 100644 --- a/src/WorkbookInterface.php +++ b/src/WorkbookInterface.php @@ -23,11 +23,12 @@ public function getWorksheets(); /** * Returns a row iterator for the current worksheet index * - * @param int $worksheetIndex + * @param int $worksheetIndex + * @param array $options * * @return \Iterator */ - public function createRowIterator($worksheetIndex); + public function createRowIterator($worksheetIndex, array $options = []); /** * Returns a worksheet index by name diff --git a/src/Xlsx/RowIterator.php b/src/Xlsx/RowIterator.php index e7617a8..31d16ed 100644 --- a/src/Xlsx/RowIterator.php +++ b/src/Xlsx/RowIterator.php @@ -35,6 +35,11 @@ class RowIterator implements \Iterator */ protected $path; + /** + * @var array + */ + protected $options; + /** * @var \XMLReader */ @@ -51,26 +56,31 @@ class RowIterator implements \Iterator protected $currentValue; /** - * @var Boolean + * @var boolean */ protected $valid; /** * Constructor * - * @param ValueTransformer $valueTransformer - * @param string $path + * @param RowBuilderFactory $rowBuilderFactory + * @param ColumnIndexTransformer $columnIndexTransformer + * @param ValueTransformer $valueTransformer + * @param string $path + * @param array $options */ public function __construct( RowBuilderFactory $rowBuilderFactory, ColumnIndexTransformer $columnIndexTransformer, ValueTransformer $valueTransformer, - $path + $path, + array $options ) { $this->rowBuilderFactory = $rowBuilderFactory; $this->columnIndexTransformer = $columnIndexTransformer; $this->valueTransformer = $valueTransformer; $this->path = $path; + $this->options = $options; } /** diff --git a/src/Xlsx/RowIteratorFactory.php b/src/Xlsx/RowIteratorFactory.php index 2b07031..e2c3928 100644 --- a/src/Xlsx/RowIteratorFactory.php +++ b/src/Xlsx/RowIteratorFactory.php @@ -53,12 +53,19 @@ public function __construct( * * @param ValueTransformer $valueTransformer the value transformer for the workbook * @param string $path the path to the extracted XML worksheet file + * @param array $options options specific to the format * * @return RowIterator */ - public function create(ValueTransformer $valueTransformer, $path) + public function create(ValueTransformer $valueTransformer, $path, array $options) { - return new $this->iteratorClass($this->rowBuilderFactory, $this->columnIndexTransformer, $valueTransformer, $path); + return new $this->iteratorClass( + $this->rowBuilderFactory, + $this->columnIndexTransformer, + $valueTransformer, + $path, + $options + ); } } diff --git a/src/Xlsx/Workbook.php b/src/Xlsx/Workbook.php index 48acc1d..a007f6e 100644 --- a/src/Xlsx/Workbook.php +++ b/src/Xlsx/Workbook.php @@ -72,7 +72,6 @@ class Workbook implements WorkbookInterface private $valueTransformer; /** - * * @var SharedStrings */ private $sharedStrings; @@ -127,11 +126,15 @@ public function getWorksheets() /** * {@inheritdoc} */ - public function createRowIterator($worksheetIndex) + public function createRowIterator($worksheetIndex, array $options = []) { $paths = array_values($this->getWorksheetPaths()); - return $this->rowIteratorFactory->create($this->getValueTransformer(), $this->archive->extract($paths[$worksheetIndex])); + return $this->rowIteratorFactory->create( + $this->getValueTransformer(), + $this->archive->extract($paths[$worksheetIndex]), + $options + ); } /** From a5d2d9213d3b1677eefff47b465664e3588c5c7b Mon Sep 17 00:00:00 2001 From: Antoine Guigan Date: Fri, 6 Jun 2014 19:25:43 +0200 Subject: [PATCH 02/22] Renamed interfaces (see CHANGELOG) --- CHANGELOG.md | 13 ++ .../Xlsx/SpreadsheetLoaderSpec.php | 138 +++++++++++ .../Xlsx/SpreadsheetSpec.php | 112 +++++++++ src/SpreadsheetInterface.php | 41 ++++ src/SpreadsheetLoaderInterface.php | 24 ++ src/SpreadsheetParser.php | 10 +- src/Xlsx/Relationships.php | 2 +- src/Xlsx/Spreadsheet.php | 214 ++++++++++++++++++ src/Xlsx/SpreadsheetLoader.php | 107 +++++++++ src/Xlsx/Styles.php | 2 +- src/Xlsx/XlsxParser.php | 16 +- 11 files changed, 664 insertions(+), 15 deletions(-) create mode 100644 CHANGELOG.md create mode 100644 spec/Akeneo/Component/SpreadsheetParser/Xlsx/SpreadsheetLoaderSpec.php create mode 100644 spec/Akeneo/Component/SpreadsheetParser/Xlsx/SpreadsheetSpec.php create mode 100644 src/SpreadsheetInterface.php create mode 100644 src/SpreadsheetLoaderInterface.php create mode 100644 src/Xlsx/Spreadsheet.php create mode 100644 src/Xlsx/SpreadsheetLoader.php diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..5d5c9b9 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,13 @@ +# CHANGELOG + +## 1.1 + +### Features + +* CSV support + +### BC Breaks + +* WorkbookInterface is now SpreasheetInterface +* WorkbookLoaderInterface is now SpreadsheetLoaderInterface + diff --git a/spec/Akeneo/Component/SpreadsheetParser/Xlsx/SpreadsheetLoaderSpec.php b/spec/Akeneo/Component/SpreadsheetParser/Xlsx/SpreadsheetLoaderSpec.php new file mode 100644 index 0000000..79f75e1 --- /dev/null +++ b/spec/Akeneo/Component/SpreadsheetParser/Xlsx/SpreadsheetLoaderSpec.php @@ -0,0 +1,138 @@ +beConstructedWith( + $archiveLoader, + $relationshipsLoader, + $sharedStringsLoader, + $stylesLoader, + $worksheetListReader, + $valueTransformerFactory, + $rowIteratorFactory, + 'spec\Akeneo\Component\SpreadsheetParser\Xlsx\StubSpreadsheet' + ); + } + + public function it_is_initializable() + { + $this->shouldHaveType('Akeneo\Component\SpreadsheetParser\Xlsx\SpreadsheetLoader'); + } + + public function it_creates_workbook_objects( + RelationshipsLoader $relationshipsLoader, + SharedStringsLoader $sharedStringsLoader, + StylesLoader $stylesLoader, + WorksheetListReader $worksheetListReader, + ValueTransformerFactory $valueTransformerFactory, + RowIteratorFactory $rowIteratorFactory, + ArchiveLoader $archiveLoader, + Archive $archive + ) { + $archiveLoader->open('path')->willReturn($archive); + + $workbook = $this->open('path'); + $workbook->getArchive()->shouldReturn($archive); + $workbook->getSharedStringsLoader()->shouldReturn($sharedStringsLoader); + $workbook->getStylesLoader()->shouldReturn($stylesLoader); + $workbook->getRowIteratorFactory()->shouldReturn($rowIteratorFactory); + $workbook->getWorksheetListReader()->shouldReturn($worksheetListReader); + $workbook->getValueTransformerFactory()->shouldReturn($valueTransformerFactory); + $workbook->getRelationshipsLoader()->shouldReturn($relationshipsLoader); + } + + public function it_caches_workbook_objects( + ArchiveLoader $archiveLoader, + Archive $archive + ) { + $archiveLoader->open('path')->shouldBeCalledTimes(1)->willReturn($archive); + + $workbook = $this->open('path'); + $workbook->getArchive()->shouldReturn($archive); + } +} + +class StubSpreadsheet +{ + protected $sharedStringsLoader; + protected $worksheetListReader; + protected $relationshipsLoader; + protected $stylesLoader; + protected $rowIteratorFactory; + protected $valueTransformerFactory; + protected $archive; + + public function __construct( + Archive $archive, + RelationshipsLoader $relationshipsLoader, + SharedStringsLoader $sharedStringsLoader, + StylesLoader $stylesLoader, + WorksheetListReader $worksheetListReader, + ValueTransformerFactory $valueTransformerFactory, + RowIteratorFactory $rowIteratorFactory + ) { + $this->archive = $archive; + $this->sharedStringsLoader = $sharedStringsLoader; + $this->relationshipsLoader = $relationshipsLoader; + $this->stylesLoader = $stylesLoader; + $this->worksheetListReader = $worksheetListReader; + $this->valueTransformerFactory = $valueTransformerFactory; + $this->rowIteratorFactory = $rowIteratorFactory; + } + + public function getSharedStringsLoader() + { + return $this->sharedStringsLoader; + } + + public function getRowIteratorFactory() + { + return $this->rowIteratorFactory; + } + + public function getArchive() + { + return $this->archive; + } + + public function getWorksheetListReader() + { + return $this->worksheetListReader; + } + + public function getRelationshipsLoader() + { + return $this->relationshipsLoader; + } + + public function getValueTransformerFactory() + { + return $this->valueTransformerFactory; + } + + public function getStylesLoader() + { + return $this->stylesLoader; + } +} diff --git a/spec/Akeneo/Component/SpreadsheetParser/Xlsx/SpreadsheetSpec.php b/spec/Akeneo/Component/SpreadsheetParser/Xlsx/SpreadsheetSpec.php new file mode 100644 index 0000000..b012d48 --- /dev/null +++ b/spec/Akeneo/Component/SpreadsheetParser/Xlsx/SpreadsheetSpec.php @@ -0,0 +1,112 @@ +beConstructedWith( + $archive, + $relationshipsLoader, + $sharedStringsLoader, + $stylesLoader, + $worksheetListReader, + $valueTransformerFactory, + $rowIteratorFactory + ); + $archive->extract(Argument::type('string'))->will( + function ($args) { + return sprintf('temp_%s', $args[0]); + } + ); + + $beCalledAtMostOnce = function ($calls, $object, $method) { + if (count($calls) > 1) { + throw new UnexpectedCallsException( + 'Method should be called at most once', + $method, + $calls + ); + } + }; + $relationshipsLoader->open('temp_' . Spreadsheet::RELATIONSHIPS_PATH) + ->should($beCalledAtMostOnce) + ->willReturn($relationships); + + $relationships->getSharedStringsPath()->willReturn('shared_strings'); + $relationships->getStylesPath()->willReturn('styles'); + + $sharedStringsLoader->open('temp_shared_strings') + ->should($beCalledAtMostOnce) + ->willReturn($sharedStrings); + + $stylesLoader->open(('temp_styles'))->willReturn($styles); + $valueTransformerFactory->create($sharedStrings, $styles)->willReturn($valueTransformer); + + $worksheetListReader->getWorksheetPaths($relationships, 'temp_' . Spreadsheet::WORKBOOK_PATH) + ->should($beCalledAtMostOnce) + ->willReturn(['sheet1' => 'path1', 'sheet2' => 'path2']); + } + + public function it_is_initializable() + { + $this->shouldHaveType('Akeneo\Component\SpreadsheetParser\Xlsx\Spreadsheet'); + } + + public function it_returns_the_worksheet_list() + { + $this->getWorksheets()->shouldReturn(['sheet1', 'sheet2']); + } + + public function it_creates_row_iterators( + ValueTransformer $valueTransformer, + RowIteratorFactory $rowIteratorFactory, + RowIterator $rowIterator1, + RowIterator $rowIterator2 + ) { + $rowIteratorFactory->create($valueTransformer, 'temp_path1', [])->willReturn($rowIterator1); + $rowIteratorFactory->create($valueTransformer, 'temp_path2', [])->willReturn($rowIterator2); + + $this->createRowIterator(0)->shouldReturn($rowIterator1); + $this->createRowIterator(1)->shouldReturn($rowIterator2); + } + + public function it_finds_a_worksheet_index_by_name() + { + $this->getWorksheetIndex('sheet2')->shouldReturn(1); + } + + public function it_returns_false_if_a_worksheet_does_not_exist() + { + $this->getWorksheetIndex('sheet3')->shouldReturn(false); + } +} diff --git a/src/SpreadsheetInterface.php b/src/SpreadsheetInterface.php new file mode 100644 index 0000000..f618897 --- /dev/null +++ b/src/SpreadsheetInterface.php @@ -0,0 +1,41 @@ + + * @copyright 2013 Akeneo SAS (http://www.akeneo.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +interface SpreadsheetInterface +{ + /** + * Returns an array containing all worksheet names + * + * The keys of the array should be the indexes of the worksheets + * + * @return array + */ + public function getWorksheets(); + + /** + * Returns a row iterator for the current worksheet index + * + * @param int $worksheetIndex + * @param array $options + * + * @return \Iterator + */ + public function createRowIterator($worksheetIndex, array $options = []); + + /** + * Returns a worksheet index by name + * + * @param string $name + * + * @return int + */ + public function getWorksheetIndex($name); +} diff --git a/src/SpreadsheetLoaderInterface.php b/src/SpreadsheetLoaderInterface.php new file mode 100644 index 0000000..f26f393 --- /dev/null +++ b/src/SpreadsheetLoaderInterface.php @@ -0,0 +1,24 @@ + + * @copyright 2013 Akeneo SAS (http://www.akeneo.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +interface SpreadsheetLoaderInterface +{ + /** + * Opens a workbook and returns a Spreadsheet object + * + * Spreadsheet objects are cached, and will be read only once + * + * @param string $path + * + * @return Spreadsheet + */ + public function open($path); +} diff --git a/src/SpreadsheetParser.php b/src/SpreadsheetParser.php index 9fa3e8f..d0dfe15 100644 --- a/src/SpreadsheetParser.php +++ b/src/SpreadsheetParser.php @@ -16,20 +16,20 @@ class SpreadsheetParser * * @param string $path * - * @return WorkbookInterface + * @return SpreadsheetInterface */ public static function open($path) { - return static::getXlsxWorkbookLoader()->open($path); + return static::getXlsxSpreadsheetLoader()->open($path); } /** * Returns the XLSX workbook loader * - * @return Xlsx\WorkbookLoader + * @return Xlsx\SpreadsheetLoader */ - public static function getXlsxWorkbookLoader() + public static function getXlsxSpreadsheetLoader() { - return Xlsx\XlsxParser::getWorkbookLoader(); + return Xlsx\XlsxParser::getSpreadsheetLoader(); } } diff --git a/src/Xlsx/Relationships.php b/src/Xlsx/Relationships.php index 0136fb8..0e8253a 100644 --- a/src/Xlsx/Relationships.php +++ b/src/Xlsx/Relationships.php @@ -3,7 +3,7 @@ namespace Akeneo\Component\SpreadsheetParser\Xlsx; /** - * Workbook relationships + * Spreadsheet relationships * * @author Antoine Guigan * @copyright 2013 Akeneo SAS (http://www.akeneo.com) diff --git a/src/Xlsx/Spreadsheet.php b/src/Xlsx/Spreadsheet.php new file mode 100644 index 0000000..eebc7b7 --- /dev/null +++ b/src/Xlsx/Spreadsheet.php @@ -0,0 +1,214 @@ + + * @copyright 2013 Akeneo SAS (http://www.akeneo.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +class Spreadsheet implements SpreadsheetInterface +{ + + /** + * @staticvar string Path to the relationships file inside the XLSX archive + */ + const RELATIONSHIPS_PATH = 'xl/_rels/workbook.xml.rels'; + + /** + * @staticvar string Path to the workbooks file inside the XLSX archive + */ + const WORKBOOK_PATH = 'xl/workbook.xml'; + + /** + * @var RelationshipsLoader + */ + protected $relationshipsLoader; + + /** + * @var ValueTransformerFactory + */ + protected $valueTransformerFactory; + + /** + * + * @var SharedStringsLoader + */ + protected $sharedStringsLoader; + + /** + * + * @var RowIteratorFactory + */ + protected $rowIteratorFactory; + + /** + * @var Archive + */ + protected $archive; + + /** + * @var StylesLoader + */ + protected $stylesLoader; + + /** + * @var WorksheetListReader + */ + protected $worksheetListReader; + + /** + * @var Relationships + */ + private $relationships; + + /** + * @var ValueTransformer + */ + private $valueTransformer; + + /** + * @var SharedStrings + */ + private $sharedStrings; + + /** + * @var array + */ + private $worksheetPaths; + + /** + * @var Styles + */ + private $styles; + + /** + * Constructor + * + * @param Archive $archive + * @param RelationshipsLoader $relationshipsLoader + * @param SharedStringsLoader $sharedStringsLoader + * @param StylesLoader $stylesLoader + * @param WorksheetListReader $worksheetListReader + * @param ValueTransformerFactory $valueTransformerFactory + * @param RowIteratorFactory $rowIteratorFactory + */ + public function __construct( + Archive $archive, + RelationshipsLoader $relationshipsLoader, + SharedStringsLoader $sharedStringsLoader, + StylesLoader $stylesLoader, + WorksheetListReader $worksheetListReader, + ValueTransformerFactory $valueTransformerFactory, + RowIteratorFactory $rowIteratorFactory + ) { + $this->archive = $archive; + $this->relationshipsLoader = $relationshipsLoader; + $this->sharedStringsLoader = $sharedStringsLoader; + $this->stylesLoader = $stylesLoader; + $this->worksheetListReader = $worksheetListReader; + $this->valueTransformerFactory = $valueTransformerFactory; + $this->rowIteratorFactory = $rowIteratorFactory; + } + + /** + * {@inheritdoc} + */ + public function getWorksheets() + { + return array_keys($this->getWorksheetPaths()); + } + + /** + * {@inheritdoc} + */ + public function createRowIterator($worksheetIndex, array $options = []) + { + $paths = array_values($this->getWorksheetPaths()); + + return $this->rowIteratorFactory->create( + $this->getValueTransformer(), + $this->archive->extract($paths[$worksheetIndex]), + $options + ); + } + + /** + * {@inheritdoc} + */ + public function getWorksheetIndex($name) + { + return array_search($name, $this->getWorksheets()); + } + + /** + * @return Relationships + */ + protected function getRelationships() + { + if (!$this->relationships) { + $path = $this->archive->extract(static::RELATIONSHIPS_PATH); + $this->relationships = $this->relationshipsLoader->open($path); + } + + return $this->relationships; + } + + /** + * @return ValueTransformer + */ + protected function getValueTransformer() + { + if (!$this->valueTransformer) { + $this->valueTransformer = $this->valueTransformerFactory->create( + $this->getSharedStrings(), + $this->getStyles() + ); + } + + return $this->valueTransformer; + } + + /** + * @return SharedStrings + */ + protected function getSharedStrings() + { + if (!$this->sharedStrings) { + $path = $this->archive->extract($this->relationships->getSharedStringsPath()); + $this->sharedStrings = $this->sharedStringsLoader->open($path); + } + + return $this->sharedStrings; + } + + /** + * @return array + */ + protected function getWorksheetPaths() + { + if (!$this->worksheetPaths) { + $path = $this->archive->extract(static::WORKBOOK_PATH); + $this->worksheetPaths = $this->worksheetListReader->getWorksheetPaths($this->getRelationships(), $path); + } + + return $this->worksheetPaths; + } + + /** + * @return Styles + */ + protected function getStyles() + { + if (!$this->styles) { + $path = $this->archive->extract($this->relationships->getStylesPath()); + $this->styles = $this->stylesLoader->open($path); + } + + return $this->styles; + } +} diff --git a/src/Xlsx/SpreadsheetLoader.php b/src/Xlsx/SpreadsheetLoader.php new file mode 100644 index 0000000..4feb54c --- /dev/null +++ b/src/Xlsx/SpreadsheetLoader.php @@ -0,0 +1,107 @@ + + * @copyright 2013 Akeneo SAS (http://www.akeneo.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +class SpreadsheetLoader implements SpreadsheetLoaderInterface +{ + /** + * @var string + */ + protected $workbookClass; + + /** + * @var RelationshipsLoader + */ + protected $relationshipsLoader; + + /** + * @var SharedStringsLoader + */ + protected $sharedStringsLoader; + + /** + * @var StylesLoader + */ + protected $stylesLoader; + + /** + * @var WorksheetListReader + */ + protected $worksheetListReader; + + /** + * @var ValueTransformerFactory + */ + protected $valueTransformerFactory; + + /** + * @var RowIteratorFactory + */ + protected $rowIteratorFactory; + + /** + * @var ArchiveLoader + */ + protected $archiveLoader; + + /** + * Constructor + * + * @param ArchiveLoader $archiveLoader + * @param RelationshipsLoader $relationshipsLoader + * @param SharedStringsLoader $sharedStringsLoader + * @param StylesLoader $stylesLoader + * @param WorksheetListReader $worksheetListReader + * @param ValueTransformerFactory $valueTransformerFactory + * @param RowIteratorFactory $rowIteratorFactory + * @param string $workbookClass + */ + public function __construct( + ArchiveLoader $archiveLoader, + RelationshipsLoader $relationshipsLoader, + SharedStringsLoader $sharedStringsLoader, + StylesLoader $stylesLoader, + WorksheetListReader $worksheetListReader, + ValueTransformerFactory $valueTransformerFactory, + RowIteratorFactory $rowIteratorFactory, + $workbookClass + ) + { + $this->relationshipsLoader = $relationshipsLoader; + $this->sharedStringsLoader = $sharedStringsLoader; + $this->stylesLoader = $stylesLoader; + $this->worksheetListReader = $worksheetListReader; + $this->valueTransformerFactory = $valueTransformerFactory; + $this->rowIteratorFactory = $rowIteratorFactory; + $this->archiveLoader = $archiveLoader; + $this->workbookClass = $workbookClass; + } + + /** + * {@inheritdoc} + */ + public function open($path) + { + $archive = $this->archiveLoader->open($path); + + return new $this->workbookClass( + $archive, + $this->relationshipsLoader, + $this->sharedStringsLoader, + $this->stylesLoader, + $this->worksheetListReader, + $this->valueTransformerFactory, + $this->rowIteratorFactory + ); + } + +} diff --git a/src/Xlsx/Styles.php b/src/Xlsx/Styles.php index b0a0072..15586a1 100644 --- a/src/Xlsx/Styles.php +++ b/src/Xlsx/Styles.php @@ -3,7 +3,7 @@ namespace Akeneo\Component\SpreadsheetParser\Xlsx; /** - * Workbook styles + * Spreadsheet styles * * @author Antoine Guigan * @copyright 2013 Akeneo SAS (http://www.akeneo.com) diff --git a/src/Xlsx/XlsxParser.php b/src/Xlsx/XlsxParser.php index c346343..0e6d884 100644 --- a/src/Xlsx/XlsxParser.php +++ b/src/Xlsx/XlsxParser.php @@ -47,12 +47,12 @@ class XlsxParser const VALUE_TRANSFORMER_CLASS = 'Akeneo\Component\SpreadsheetParser\Xlsx\ValueTransformer'; /** - * @staticvar string Workbook class + * @staticvar string Spreadsheet class */ - const WORKBOOK_CLASS = 'Akeneo\Component\SpreadsheetParser\Xlsx\Workbook'; + const WORKBOOK_CLASS = 'Akeneo\Component\SpreadsheetParser\Xlsx\Spreadsheet'; /** - * @var WorkbookLoader + * @var SpreadsheetLoader */ private static $workbookLoader; @@ -61,20 +61,20 @@ class XlsxParser * * @param string $path * - * @return Workbook + * @return Spreadsheet */ public static function open($path) { - return static::getWorkbookLoader()->open($path); + return static::getSpreadsheetLoader()->open($path); } /** - * @return WorkbookLoader + * @return SpreadsheetLoader */ - public static function getWorkbookLoader() + public static function getSpreadsheetLoader() { if (!isset(self::$workbookLoader)) { - self::$workbookLoader = new WorkbookLoader( + self::$workbookLoader = new SpreadsheetLoader( static::createArchiveLoader(), static::createRelationshipsLoader(), static::createSharedStringsLoader(), From ba3b2176aa78078c2357a62478fdb3012bf36f97 Mon Sep 17 00:00:00 2001 From: Antoine Guigan Date: Fri, 6 Jun 2014 19:26:25 +0200 Subject: [PATCH 03/22] Renamed interfaces (see CHANGELOG) --- .../Xlsx/WorkbookLoaderSpec.php | 138 ----------- .../SpreadsheetParser/Xlsx/WorkbookSpec.php | 112 --------- src/WorkbookInterface.php | 41 ---- src/WorkbookLoaderInterface.php | 24 -- src/Xlsx/Workbook.php | 214 ------------------ src/Xlsx/WorkbookLoader.php | 107 --------- 6 files changed, 636 deletions(-) delete mode 100644 spec/Akeneo/Component/SpreadsheetParser/Xlsx/WorkbookLoaderSpec.php delete mode 100644 spec/Akeneo/Component/SpreadsheetParser/Xlsx/WorkbookSpec.php delete mode 100644 src/WorkbookInterface.php delete mode 100644 src/WorkbookLoaderInterface.php delete mode 100644 src/Xlsx/Workbook.php delete mode 100644 src/Xlsx/WorkbookLoader.php diff --git a/spec/Akeneo/Component/SpreadsheetParser/Xlsx/WorkbookLoaderSpec.php b/spec/Akeneo/Component/SpreadsheetParser/Xlsx/WorkbookLoaderSpec.php deleted file mode 100644 index 8e40733..0000000 --- a/spec/Akeneo/Component/SpreadsheetParser/Xlsx/WorkbookLoaderSpec.php +++ /dev/null @@ -1,138 +0,0 @@ -beConstructedWith( - $archiveLoader, - $relationshipsLoader, - $sharedStringsLoader, - $stylesLoader, - $worksheetListReader, - $valueTransformerFactory, - $rowIteratorFactory, - 'spec\Akeneo\Component\SpreadsheetParser\Xlsx\StubWorkbook' - ); - } - - public function it_is_initializable() - { - $this->shouldHaveType('Akeneo\Component\SpreadsheetParser\Xlsx\WorkbookLoader'); - } - - public function it_creates_workbook_objects( - RelationshipsLoader $relationshipsLoader, - SharedStringsLoader $sharedStringsLoader, - StylesLoader $stylesLoader, - WorksheetListReader $worksheetListReader, - ValueTransformerFactory $valueTransformerFactory, - RowIteratorFactory $rowIteratorFactory, - ArchiveLoader $archiveLoader, - Archive $archive - ) { - $archiveLoader->open('path')->willReturn($archive); - - $workbook = $this->open('path'); - $workbook->getArchive()->shouldReturn($archive); - $workbook->getSharedStringsLoader()->shouldReturn($sharedStringsLoader); - $workbook->getStylesLoader()->shouldReturn($stylesLoader); - $workbook->getRowIteratorFactory()->shouldReturn($rowIteratorFactory); - $workbook->getWorksheetListReader()->shouldReturn($worksheetListReader); - $workbook->getValueTransformerFactory()->shouldReturn($valueTransformerFactory); - $workbook->getRelationshipsLoader()->shouldReturn($relationshipsLoader); - } - - public function it_caches_workbook_objects( - ArchiveLoader $archiveLoader, - Archive $archive - ) { - $archiveLoader->open('path')->shouldBeCalledTimes(1)->willReturn($archive); - - $workbook = $this->open('path'); - $workbook->getArchive()->shouldReturn($archive); - } -} - -class StubWorkbook -{ - protected $sharedStringsLoader; - protected $worksheetListReader; - protected $relationshipsLoader; - protected $stylesLoader; - protected $rowIteratorFactory; - protected $valueTransformerFactory; - protected $archive; - - public function __construct( - Archive $archive, - RelationshipsLoader $relationshipsLoader, - SharedStringsLoader $sharedStringsLoader, - StylesLoader $stylesLoader, - WorksheetListReader $worksheetListReader, - ValueTransformerFactory $valueTransformerFactory, - RowIteratorFactory $rowIteratorFactory - ) { - $this->archive = $archive; - $this->sharedStringsLoader = $sharedStringsLoader; - $this->relationshipsLoader = $relationshipsLoader; - $this->stylesLoader = $stylesLoader; - $this->worksheetListReader = $worksheetListReader; - $this->valueTransformerFactory = $valueTransformerFactory; - $this->rowIteratorFactory = $rowIteratorFactory; - } - - public function getSharedStringsLoader() - { - return $this->sharedStringsLoader; - } - - public function getRowIteratorFactory() - { - return $this->rowIteratorFactory; - } - - public function getArchive() - { - return $this->archive; - } - - public function getWorksheetListReader() - { - return $this->worksheetListReader; - } - - public function getRelationshipsLoader() - { - return $this->relationshipsLoader; - } - - public function getValueTransformerFactory() - { - return $this->valueTransformerFactory; - } - - public function getStylesLoader() - { - return $this->stylesLoader; - } -} diff --git a/spec/Akeneo/Component/SpreadsheetParser/Xlsx/WorkbookSpec.php b/spec/Akeneo/Component/SpreadsheetParser/Xlsx/WorkbookSpec.php deleted file mode 100644 index 45f518c..0000000 --- a/spec/Akeneo/Component/SpreadsheetParser/Xlsx/WorkbookSpec.php +++ /dev/null @@ -1,112 +0,0 @@ -beConstructedWith( - $archive, - $relationshipsLoader, - $sharedStringsLoader, - $stylesLoader, - $worksheetListReader, - $valueTransformerFactory, - $rowIteratorFactory - ); - $archive->extract(Argument::type('string'))->will( - function ($args) { - return sprintf('temp_%s', $args[0]); - } - ); - - $beCalledAtMostOnce = function ($calls, $object, $method) { - if (count($calls) > 1) { - throw new UnexpectedCallsException( - 'Method should be called at most once', - $method, - $calls - ); - } - }; - $relationshipsLoader->open('temp_' . Workbook::RELATIONSHIPS_PATH) - ->should($beCalledAtMostOnce) - ->willReturn($relationships); - - $relationships->getSharedStringsPath()->willReturn('shared_strings'); - $relationships->getStylesPath()->willReturn('styles'); - - $sharedStringsLoader->open('temp_shared_strings') - ->should($beCalledAtMostOnce) - ->willReturn($sharedStrings); - - $stylesLoader->open(('temp_styles'))->willReturn($styles); - $valueTransformerFactory->create($sharedStrings, $styles)->willReturn($valueTransformer); - - $worksheetListReader->getWorksheetPaths($relationships, 'temp_' . Workbook::WORKBOOK_PATH) - ->should($beCalledAtMostOnce) - ->willReturn(['sheet1' => 'path1', 'sheet2' => 'path2']); - } - - public function it_is_initializable() - { - $this->shouldHaveType('Akeneo\Component\SpreadsheetParser\Xlsx\Workbook'); - } - - public function it_returns_the_worksheet_list() - { - $this->getWorksheets()->shouldReturn(['sheet1', 'sheet2']); - } - - public function it_creates_row_iterators( - ValueTransformer $valueTransformer, - RowIteratorFactory $rowIteratorFactory, - RowIterator $rowIterator1, - RowIterator $rowIterator2 - ) { - $rowIteratorFactory->create($valueTransformer, 'temp_path1', [])->willReturn($rowIterator1); - $rowIteratorFactory->create($valueTransformer, 'temp_path2', [])->willReturn($rowIterator2); - - $this->createRowIterator(0)->shouldReturn($rowIterator1); - $this->createRowIterator(1)->shouldReturn($rowIterator2); - } - - public function it_finds_a_worksheet_index_by_name() - { - $this->getWorksheetIndex('sheet2')->shouldReturn(1); - } - - public function it_returns_false_if_a_worksheet_does_not_exist() - { - $this->getWorksheetIndex('sheet3')->shouldReturn(false); - } -} diff --git a/src/WorkbookInterface.php b/src/WorkbookInterface.php deleted file mode 100644 index 88de05c..0000000 --- a/src/WorkbookInterface.php +++ /dev/null @@ -1,41 +0,0 @@ - - * @copyright 2013 Akeneo SAS (http://www.akeneo.com) - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) - */ -interface WorkbookInterface -{ - /** - * Returns an array containing all worksheet names - * - * The keys of the array should be the indexes of the worksheets - * - * @return array - */ - public function getWorksheets(); - - /** - * Returns a row iterator for the current worksheet index - * - * @param int $worksheetIndex - * @param array $options - * - * @return \Iterator - */ - public function createRowIterator($worksheetIndex, array $options = []); - - /** - * Returns a worksheet index by name - * - * @param string $name - * - * @return int - */ - public function getWorksheetIndex($name); -} diff --git a/src/WorkbookLoaderInterface.php b/src/WorkbookLoaderInterface.php deleted file mode 100644 index 325ea07..0000000 --- a/src/WorkbookLoaderInterface.php +++ /dev/null @@ -1,24 +0,0 @@ - - * @copyright 2013 Akeneo SAS (http://www.akeneo.com) - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) - */ -interface WorkbookLoaderInterface -{ - /** - * Opens a workbook and returns a Workbook object - * - * Workbook objects are cached, and will be read only once - * - * @param string $path - * - * @return Workbook - */ - public function open($path); -} diff --git a/src/Xlsx/Workbook.php b/src/Xlsx/Workbook.php deleted file mode 100644 index a007f6e..0000000 --- a/src/Xlsx/Workbook.php +++ /dev/null @@ -1,214 +0,0 @@ - - * @copyright 2013 Akeneo SAS (http://www.akeneo.com) - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) - */ -class Workbook implements WorkbookInterface -{ - - /** - * @staticvar string Path to the relationships file inside the XLSX archive - */ - const RELATIONSHIPS_PATH = 'xl/_rels/workbook.xml.rels'; - - /** - * @staticvar string Path to the workbooks file inside the XLSX archive - */ - const WORKBOOK_PATH = 'xl/workbook.xml'; - - /** - * @var RelationshipsLoader - */ - protected $relationshipsLoader; - - /** - * @var ValueTransformerFactory - */ - protected $valueTransformerFactory; - - /** - * - * @var SharedStringsLoader - */ - protected $sharedStringsLoader; - - /** - * - * @var RowIteratorFactory - */ - protected $rowIteratorFactory; - - /** - * @var Archive - */ - protected $archive; - - /** - * @var StylesLoader - */ - protected $stylesLoader; - - /** - * @var WorksheetListReader - */ - protected $worksheetListReader; - - /** - * @var Relationships - */ - private $relationships; - - /** - * @var ValueTransformer - */ - private $valueTransformer; - - /** - * @var SharedStrings - */ - private $sharedStrings; - - /** - * @var array - */ - private $worksheetPaths; - - /** - * @var Styles - */ - private $styles; - - /** - * Constructor - * - * @param Archive $archive - * @param RelationshipsLoader $relationshipsLoader - * @param SharedStringsLoader $sharedStringsLoader - * @param StylesLoader $stylesLoader - * @param WorksheetListReader $worksheetListReader - * @param ValueTransformerFactory $valueTransformerFactory - * @param RowIteratorFactory $rowIteratorFactory - */ - public function __construct( - Archive $archive, - RelationshipsLoader $relationshipsLoader, - SharedStringsLoader $sharedStringsLoader, - StylesLoader $stylesLoader, - WorksheetListReader $worksheetListReader, - ValueTransformerFactory $valueTransformerFactory, - RowIteratorFactory $rowIteratorFactory - ) { - $this->archive = $archive; - $this->relationshipsLoader = $relationshipsLoader; - $this->sharedStringsLoader = $sharedStringsLoader; - $this->stylesLoader = $stylesLoader; - $this->worksheetListReader = $worksheetListReader; - $this->valueTransformerFactory = $valueTransformerFactory; - $this->rowIteratorFactory = $rowIteratorFactory; - } - - /** - * {@inheritdoc} - */ - public function getWorksheets() - { - return array_keys($this->getWorksheetPaths()); - } - - /** - * {@inheritdoc} - */ - public function createRowIterator($worksheetIndex, array $options = []) - { - $paths = array_values($this->getWorksheetPaths()); - - return $this->rowIteratorFactory->create( - $this->getValueTransformer(), - $this->archive->extract($paths[$worksheetIndex]), - $options - ); - } - - /** - * {@inheritdoc} - */ - public function getWorksheetIndex($name) - { - return array_search($name, $this->getWorksheets()); - } - - /** - * @return Relationships - */ - protected function getRelationships() - { - if (!$this->relationships) { - $path = $this->archive->extract(static::RELATIONSHIPS_PATH); - $this->relationships = $this->relationshipsLoader->open($path); - } - - return $this->relationships; - } - - /** - * @return ValueTransformer - */ - protected function getValueTransformer() - { - if (!$this->valueTransformer) { - $this->valueTransformer = $this->valueTransformerFactory->create( - $this->getSharedStrings(), - $this->getStyles() - ); - } - - return $this->valueTransformer; - } - - /** - * @return SharedStrings - */ - protected function getSharedStrings() - { - if (!$this->sharedStrings) { - $path = $this->archive->extract($this->relationships->getSharedStringsPath()); - $this->sharedStrings = $this->sharedStringsLoader->open($path); - } - - return $this->sharedStrings; - } - - /** - * @return array - */ - protected function getWorksheetPaths() - { - if (!$this->worksheetPaths) { - $path = $this->archive->extract(static::WORKBOOK_PATH); - $this->worksheetPaths = $this->worksheetListReader->getWorksheetPaths($this->getRelationships(), $path); - } - - return $this->worksheetPaths; - } - - /** - * @return Styles - */ - protected function getStyles() - { - if (!$this->styles) { - $path = $this->archive->extract($this->relationships->getStylesPath()); - $this->styles = $this->stylesLoader->open($path); - } - - return $this->styles; - } -} diff --git a/src/Xlsx/WorkbookLoader.php b/src/Xlsx/WorkbookLoader.php deleted file mode 100644 index 34bd42b..0000000 --- a/src/Xlsx/WorkbookLoader.php +++ /dev/null @@ -1,107 +0,0 @@ - - * @copyright 2013 Akeneo SAS (http://www.akeneo.com) - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) - */ -class WorkbookLoader implements WorkbookLoaderInterface -{ - /** - * @var string - */ - protected $workbookClass; - - /** - * @var RelationshipsLoader - */ - protected $relationshipsLoader; - - /** - * @var SharedStringsLoader - */ - protected $sharedStringsLoader; - - /** - * @var StylesLoader - */ - protected $stylesLoader; - - /** - * @var WorksheetListReader - */ - protected $worksheetListReader; - - /** - * @var ValueTransformerFactory - */ - protected $valueTransformerFactory; - - /** - * @var RowIteratorFactory - */ - protected $rowIteratorFactory; - - /** - * @var ArchiveLoader - */ - protected $archiveLoader; - - /** - * Constructor - * - * @param ArchiveLoader $archiveLoader - * @param RelationshipsLoader $relationshipsLoader - * @param SharedStringsLoader $sharedStringsLoader - * @param StylesLoader $stylesLoader - * @param WorksheetListReader $worksheetListReader - * @param ValueTransformerFactory $valueTransformerFactory - * @param RowIteratorFactory $rowIteratorFactory - * @param string $workbookClass - */ - public function __construct( - ArchiveLoader $archiveLoader, - RelationshipsLoader $relationshipsLoader, - SharedStringsLoader $sharedStringsLoader, - StylesLoader $stylesLoader, - WorksheetListReader $worksheetListReader, - ValueTransformerFactory $valueTransformerFactory, - RowIteratorFactory $rowIteratorFactory, - $workbookClass - ) - { - $this->relationshipsLoader = $relationshipsLoader; - $this->sharedStringsLoader = $sharedStringsLoader; - $this->stylesLoader = $stylesLoader; - $this->worksheetListReader = $worksheetListReader; - $this->valueTransformerFactory = $valueTransformerFactory; - $this->rowIteratorFactory = $rowIteratorFactory; - $this->archiveLoader = $archiveLoader; - $this->workbookClass = $workbookClass; - } - - /** - * {@inheritdoc} - */ - public function open($path) - { - $archive = $this->archiveLoader->open($path); - - return new $this->workbookClass( - $archive, - $this->relationshipsLoader, - $this->sharedStringsLoader, - $this->stylesLoader, - $this->worksheetListReader, - $this->valueTransformerFactory, - $this->rowIteratorFactory - ); - } - -} From 8b193c38cd1fcefac451ec85bd1e641da12ec0f9 Mon Sep 17 00:00:00 2001 From: Antoine Guigan Date: Fri, 6 Jun 2014 21:07:38 +0200 Subject: [PATCH 04/22] Added RowIterator for CSV --- composer.json | 3 + .../Csv/RowIteratorFactorySpec.php | 46 ++++++ .../SpreadsheetParser/Csv/RowIteratorSpec.php | 61 ++++++++ .../SpreadsheetParser/Csv/fixtures/test.csv | 2 + .../Csv/fixtures/with_options.csv | 2 + src/Csv/RowIterator.php | 136 ++++++++++++++++++ src/Csv/RowIteratorFactory.php | 43 ++++++ 7 files changed, 293 insertions(+) create mode 100644 spec/Akeneo/Component/SpreadsheetParser/Csv/RowIteratorFactorySpec.php create mode 100644 spec/Akeneo/Component/SpreadsheetParser/Csv/RowIteratorSpec.php create mode 100644 spec/Akeneo/Component/SpreadsheetParser/Csv/fixtures/test.csv create mode 100644 spec/Akeneo/Component/SpreadsheetParser/Csv/fixtures/with_options.csv create mode 100644 src/Csv/RowIterator.php create mode 100644 src/Csv/RowIteratorFactory.php diff --git a/composer.json b/composer.json index fadf753..7e201a6 100644 --- a/composer.json +++ b/composer.json @@ -16,6 +16,9 @@ "homepage": "http://akeneo.com" } ], + "require": { + "symfony/options-resolver": "2.*" + }, "require-dev": { "phpspec/phpspec": "2.0.*@dev" }, diff --git a/spec/Akeneo/Component/SpreadsheetParser/Csv/RowIteratorFactorySpec.php b/spec/Akeneo/Component/SpreadsheetParser/Csv/RowIteratorFactorySpec.php new file mode 100644 index 0000000..2e85a69 --- /dev/null +++ b/spec/Akeneo/Component/SpreadsheetParser/Csv/RowIteratorFactorySpec.php @@ -0,0 +1,46 @@ +beConstructedWith( + 'spec\Akeneo\Component\SpreadsheetParser\Csv\StubRowIterator' + ); + } + + public function it_is_initializable() + { + $this->shouldHaveType('Akeneo\Component\SpreadsheetParser\Csv\RowIteratorFactory'); + } + + public function it_creates_row_iterators( + ) { + $iterator = $this->create('path', ['options']); + $iterator->getPath()->shouldReturn('path'); + $iterator->getOptions()->shouldReturn(['options']); + } +} + +class StubRowIterator +{ + protected $path; + protected $options; + public function __construct($path, $options) + { + $this->path = $path; + $this->options = $options; + } + public function getOptions() + { + return $this->options; + } + public function getPath() + { + return $this->path; + } +} diff --git a/spec/Akeneo/Component/SpreadsheetParser/Csv/RowIteratorSpec.php b/spec/Akeneo/Component/SpreadsheetParser/Csv/RowIteratorSpec.php new file mode 100644 index 0000000..df47d84 --- /dev/null +++ b/spec/Akeneo/Component/SpreadsheetParser/Csv/RowIteratorSpec.php @@ -0,0 +1,61 @@ +beConstructedWith('path', []); + $this->shouldHaveType('Akeneo\Component\SpreadsheetParser\Csv\RowIterator'); + } + + public function it_parses_csv_files() + { + $this->beConstructedWith(__DIR__ . '/fixtures/test.csv' , []); + $this->rewind(); + foreach ($this->values as $i=>$row) { + $this->key()->shouldReturn($i); + $this->valid()->shouldReturn(true); + $this->current()->shouldReturn($row); + $this->next(); + } + $this->valid()->shouldReturn(false); + } + + public function it_can_be_rewinded() + { + $this->beConstructedWith(__DIR__ . '/fixtures/test.csv' , []); + $this->rewind(); + $this->current()->shouldReturn($this->values[0]); + $this->next(); + $this->rewind(); + $this->current()->shouldReturn($this->values[0]); + } + + public function it_accepts_options() + { + $this->beConstructedWith( + __DIR__ . '/fixtures/with_options.csv', + [ + 'delimiter' => '|', + 'enclosure' => "@" + ] + ); + $this->rewind(); + foreach ($this->values as $i => $row) { + $this->key()->shouldReturn($i); + $this->valid()->shouldReturn(true); + $this->current()->shouldReturn($row); + $this->next(); + } + $this->valid()->shouldReturn(false); + } +} diff --git a/spec/Akeneo/Component/SpreadsheetParser/Csv/fixtures/test.csv b/spec/Akeneo/Component/SpreadsheetParser/Csv/fixtures/test.csv new file mode 100644 index 0000000..df62973 --- /dev/null +++ b/spec/Akeneo/Component/SpreadsheetParser/Csv/fixtures/test.csv @@ -0,0 +1,2 @@ +value,"enclosed value",15 +,value2, \ No newline at end of file diff --git a/spec/Akeneo/Component/SpreadsheetParser/Csv/fixtures/with_options.csv b/spec/Akeneo/Component/SpreadsheetParser/Csv/fixtures/with_options.csv new file mode 100644 index 0000000..cfe8a11 --- /dev/null +++ b/spec/Akeneo/Component/SpreadsheetParser/Csv/fixtures/with_options.csv @@ -0,0 +1,2 @@ +value|@enclosed value@|15 +|value2| \ No newline at end of file diff --git a/src/Csv/RowIterator.php b/src/Csv/RowIterator.php new file mode 100644 index 0000000..1a27fcf --- /dev/null +++ b/src/Csv/RowIterator.php @@ -0,0 +1,136 @@ + + * @copyright 2013 Akeneo SAS (http://www.akeneo.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +class RowIterator implements \Iterator +{ + /** + * @var string + */ + protected $path; + + /** + * @var array + */ + protected $options; + + /** + * @var int + */ + protected $fileHandle; + + /** + * @var array + */ + protected $currentKey; + + /** + * @var array + */ + protected $currentValue; + + /** + * @var boolean + */ + protected $valid; + + /** + * Constructor + * + * @param string $path + * @param array $options + */ + public function __construct( + $path, + array $options + ) { + $this->path = $path; + $resolver = new OptionsResolver; + $this->setDefaultOptions($resolver); + $this->options = $resolver->resolve($options); + } + + /** + * {@inheritdoc} + */ + public function current() + { + return $this->currentValue; + } + + /** + * {@inheritdoc} + */ + public function key() + { + return $this->currentKey; + } + + /** + * {@inheritdoc} + */ + public function next() + { + $this->currentValue = fgetcsv( + $this->fileHandle, + $this->options['length'], + $this->options['delimiter'], + $this->options['enclosure'], + $this->options['escape'] + ); + $this->currentKey++; + $this->valid = (false !== $this->currentValue); + } + + /** + * {@inheritdoc} + */ + public function rewind() + { + if ($this->fileHandle) { + rewind($this->fileHandle); + } else { + $this->fileHandle = fopen($this->path, 'r'); + } + $this->currentKey = -1; + $this->next(); + } + + /** + * {@inheritdoc} + */ + public function valid() + { + return $this->valid; + } + + /** + * + * @param OptionsResolverInterface $resolver + */ + protected function setDefaultOptions(OptionsResolverInterface $resolver) + { + $resolver->setDefaults( + [ + 'length' => null, + 'delimiter' => ',', + 'enclosure' => '"', + 'escape' => '\\' + ] + ); + } +} diff --git a/src/Csv/RowIteratorFactory.php b/src/Csv/RowIteratorFactory.php new file mode 100644 index 0000000..5a6306f --- /dev/null +++ b/src/Csv/RowIteratorFactory.php @@ -0,0 +1,43 @@ + + * @copyright 2013 Akeneo SAS (http://www.akeneo.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +class RowIteratorFactory +{ + /** + * + * @var string + */ + protected $iteratorClass; + + /** + * Constructor + * + * @param string $iteratorClass the class for row iterators + */ + public function __construct($iteratorClass) + { + $this->iteratorClass = $iteratorClass; + } + + /** + * Creates a row iterator for the XML given worksheet file + * + * @param string $path the path to the extracted XML worksheet file + * @param array $options options specific to the format + * + * @return RowIterator + */ + public function create($path, array $options) + { + return new $this->iteratorClass($path, $options); + } + +} From 2e4c00c38c0c8d7ee90acc39a4b3fc21cc67d2ea Mon Sep 17 00:00:00 2001 From: Antoine Guigan Date: Fri, 6 Jun 2014 21:10:18 +0200 Subject: [PATCH 05/22] Fixed PHPDOC --- src/Csv/RowIterator.php | 3 ++- src/Csv/RowIteratorFactory.php | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Csv/RowIterator.php b/src/Csv/RowIterator.php index 1a27fcf..a8f25b0 100644 --- a/src/Csv/RowIterator.php +++ b/src/Csv/RowIterator.php @@ -119,7 +119,8 @@ public function valid() } /** - * + * Sets the default options + * * @param OptionsResolverInterface $resolver */ protected function setDefaultOptions(OptionsResolverInterface $resolver) diff --git a/src/Csv/RowIteratorFactory.php b/src/Csv/RowIteratorFactory.php index 5a6306f..64364de 100644 --- a/src/Csv/RowIteratorFactory.php +++ b/src/Csv/RowIteratorFactory.php @@ -12,7 +12,6 @@ class RowIteratorFactory { /** - * * @var string */ protected $iteratorClass; From ba5ca9f972a3f8a9d2b1ffcb8a556e6dab36ab5e Mon Sep 17 00:00:00 2001 From: Antoine Guigan Date: Sat, 7 Jun 2014 10:44:07 +0200 Subject: [PATCH 06/22] Completed CSV implementation --- .../Csv/SpreadsheetLoaderSpec.php | 58 ++++++++++++++++ .../SpreadsheetParser/Csv/SpreadsheetSpec.php | 47 +++++++++++++ .../SpreadsheetLoaderSpec.php | 31 +++++++++ src/Csv/CsvParser.php | 61 +++++++++++++++++ src/Csv/RowIterator.php | 2 +- src/Csv/Spreadsheet.php | 68 +++++++++++++++++++ src/Csv/SpreadsheetLoader.php | 58 ++++++++++++++++ src/SpreadsheetLoader.php | 63 +++++++++++++++++ src/SpreadsheetParser.php | 25 +++++-- 9 files changed, 407 insertions(+), 6 deletions(-) create mode 100644 spec/Akeneo/Component/SpreadsheetParser/Csv/SpreadsheetLoaderSpec.php create mode 100644 spec/Akeneo/Component/SpreadsheetParser/Csv/SpreadsheetSpec.php create mode 100644 spec/Akeneo/Component/SpreadsheetParser/SpreadsheetLoaderSpec.php create mode 100644 src/Csv/CsvParser.php create mode 100644 src/Csv/Spreadsheet.php create mode 100644 src/Csv/SpreadsheetLoader.php create mode 100644 src/SpreadsheetLoader.php diff --git a/spec/Akeneo/Component/SpreadsheetParser/Csv/SpreadsheetLoaderSpec.php b/spec/Akeneo/Component/SpreadsheetParser/Csv/SpreadsheetLoaderSpec.php new file mode 100644 index 0000000..b155000 --- /dev/null +++ b/spec/Akeneo/Component/SpreadsheetParser/Csv/SpreadsheetLoaderSpec.php @@ -0,0 +1,58 @@ +beConstructedWith( + $rowIteratorFactory, + 'spec\Akeneo\Component\SpreadsheetParser\Csv\StubSpreadsheet', + 'sheet' + ); + } + + public function it_is_initializable() + { + $this->shouldHaveType('Akeneo\Component\SpreadsheetParser\Csv\SpreadsheetLoader'); + } + + public function it_creates_workbook_objects( + RowIteratorFactory $rowIteratorFactory + ) { + $workbook = $this->open('path'); + $workbook->getPath()->shouldReturn('path'); + $workbook->getSheetName()->shouldReturn('sheet'); + $workbook->getRowIteratorFactory()->shouldReturn($rowIteratorFactory); + } +} + +class StubSpreadsheet +{ + protected $rowIteratorFactory; + protected $sheetName; + protected $path; + public function __construct($rowIteratorFactory, $sheetName, $path) + { + $this->rowIteratorFactory = $rowIteratorFactory; + $this->sheetName = $sheetName; + $this->path = $path; + } + public function getRowIteratorFactory() + { + return $this->rowIteratorFactory; + } + public function getSheetName() + { + return $this->sheetName; + } + public function getPath() + { + return $this->path; + } +} diff --git a/spec/Akeneo/Component/SpreadsheetParser/Csv/SpreadsheetSpec.php b/spec/Akeneo/Component/SpreadsheetParser/Csv/SpreadsheetSpec.php new file mode 100644 index 0000000..eea5d0f --- /dev/null +++ b/spec/Akeneo/Component/SpreadsheetParser/Csv/SpreadsheetSpec.php @@ -0,0 +1,47 @@ +beConstructedWith($rowIteratorFactory, 'sheet', 'path'); + } + + public function it_is_initializable() + { + $this->shouldHaveType('Akeneo\Component\SpreadsheetParser\Csv\Spreadsheet'); + } + + public function it_returns_the_worksheet_list() + { + $this->getWorksheets()->shouldReturn(['sheet']); + } + + public function it_creates_row_iterators( + RowIteratorFactory $rowIteratorFactory, + RowIterator $rowIterator1, + RowIterator $rowIterator2 + ) { + $rowIteratorFactory->create('path', ['options1'])->willReturn($rowIterator1); + $rowIteratorFactory->create('path', ['options2'])->willReturn($rowIterator2); + + $this->createRowIterator(0, ['options1'])->shouldReturn($rowIterator1); + $this->createRowIterator(1, ['options2'])->shouldReturn($rowIterator2); + } + + public function it_finds_a_worksheet_index_by_name() + { + $this->getWorksheetIndex('sheet')->shouldReturn(0); + } + + public function it_returns_false_if_a_worksheet_does_not_exist() + { + $this->getWorksheetIndex('sheet3')->shouldReturn(false); + } +} diff --git a/spec/Akeneo/Component/SpreadsheetParser/SpreadsheetLoaderSpec.php b/spec/Akeneo/Component/SpreadsheetParser/SpreadsheetLoaderSpec.php new file mode 100644 index 0000000..ef8e345 --- /dev/null +++ b/spec/Akeneo/Component/SpreadsheetParser/SpreadsheetLoaderSpec.php @@ -0,0 +1,31 @@ +addLoader('extension', $loader); + $loader->open('file.extension')->willReturn($spreadsheet); + $this->addLoader('other_extension', $otherLoader); + } + + public function it_is_initializable() + { + $this->shouldHaveType('Akeneo\Component\SpreadsheetParser\SpreadsheetLoader'); + } + + public function it_uses_the_loader_corresponding_to_the_file_extension( + SpreadsheetInterface $spreadsheet + ) { + $this->open('file.extension')->shouldReturn($spreadsheet); + } +} diff --git a/src/Csv/CsvParser.php b/src/Csv/CsvParser.php new file mode 100644 index 0000000..b4987d4 --- /dev/null +++ b/src/Csv/CsvParser.php @@ -0,0 +1,61 @@ + + */ +class CsvParser +{ + /** + * @staticvar string Spreadsheet class + */ + const WORKBOOK_CLASS = 'Akeneo\Component\SpreadsheetParser\Csv\Spreadsheet'; + + /** + * @staticvar string RowIterator class + */ + const ROW_ITERATOR_CLASS = 'Akeneo\Component\SpreadsheetParser\Csv\RowIterator'; + + /** + * @var SpreadsheetLoader + */ + private static $workbookLoader; + + /** + * Opens a CSV file + * + * @param string $path + * + * @return Spreadsheet + */ + public static function open($path) + { + return static::getSpreadsheetLoader()->open($path); + } + + /** + * @return SpreadsheetLoader + */ + public static function getSpreadsheetLoader() + { + if (!isset(self::$workbookLoader)) { + self::$workbookLoader = new SpreadsheetLoader( + static::createRowIteratorFactory(), + static::WORKBOOK_CLASS + ); + } + + return self::$workbookLoader; + } + + /** + * @return RowIteratorFactory + */ + protected static function createRowIteratorFactory() + { + return new RowIteratorFactory(static::ROW_ITERATOR_CLASS); + } +} diff --git a/src/Csv/RowIterator.php b/src/Csv/RowIterator.php index a8f25b0..ac75b32 100644 --- a/src/Csv/RowIterator.php +++ b/src/Csv/RowIterator.php @@ -120,7 +120,7 @@ public function valid() /** * Sets the default options - * + * * @param OptionsResolverInterface $resolver */ protected function setDefaultOptions(OptionsResolverInterface $resolver) diff --git a/src/Csv/Spreadsheet.php b/src/Csv/Spreadsheet.php new file mode 100644 index 0000000..e14442a --- /dev/null +++ b/src/Csv/Spreadsheet.php @@ -0,0 +1,68 @@ + + * @copyright 2013 Akeneo SAS (http://www.akeneo.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +class Spreadsheet implements SpreadsheetInterface +{ + /** + * @var RowIteratorFactory + */ + protected $rowIteratorFactory; + + /** + * @var string + */ + protected $sheetName; + + /** + * @var string + */ + protected $path; + + /** + * Constructor + * + * @param RowIteratorFactory $rowIteratorFactory + * @param string $sheetName + * @param string $path + */ + public function __construct(RowIteratorFactory $rowIteratorFactory, $sheetName, $path) + { + $this->rowIteratorFactory = $rowIteratorFactory; + $this->sheetName = $sheetName; + $this->path = $path; + } + + /** + * {@inheritdoc} + */ + public function getWorksheets() + { + return [$this->sheetName]; + } + + /** + * {@inheritdoc} + */ + public function createRowIterator($worksheetIndex, array $options = []) + { + return $this->rowIteratorFactory->create($this->path, $options); + } + + /** + * {@inheritdoc} + */ + public function getWorksheetIndex($name) + { + return $this->sheetName === $name ? 0 : false; + } +} diff --git a/src/Csv/SpreadsheetLoader.php b/src/Csv/SpreadsheetLoader.php new file mode 100644 index 0000000..04ee65e --- /dev/null +++ b/src/Csv/SpreadsheetLoader.php @@ -0,0 +1,58 @@ + + * @copyright 2013 Akeneo SAS (http://www.akeneo.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +class SpreadsheetLoader implements SpreadsheetLoaderInterface +{ + /** + * @var RowIteratorFactory + */ + protected $rowIteratorFactory; + + /** + * @var string + */ + protected $workbookClass; + + /** + * + * @var string + */ + protected $sheetName; + + /** + * Constructor + * + * @param RowIteratorFactory $rowIteratorFactory + * @param string $workbookClass + * @param string $sheetName + */ + public function __construct(RowIteratorFactory $rowIteratorFactory, $workbookClass, $sheetName) + { + $this->rowIteratorFactory = $rowIteratorFactory; + $this->workbookClass = $workbookClass; + $this->sheetName = $sheetName; + } + + /** + * {@inheritdoc} + */ + public function open($path) + { + return new $this->workbookClass( + $this->rowIteratorFactory, + $this->sheetName, + $path + ); + } + +} diff --git a/src/SpreadsheetLoader.php b/src/SpreadsheetLoader.php new file mode 100644 index 0000000..5758cff --- /dev/null +++ b/src/SpreadsheetLoader.php @@ -0,0 +1,63 @@ + + * @copyright 2013 Akeneo SAS (http://www.akeneo.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +class SpreadsheetLoader implements SpreadsheetLoaderInterface +{ + /** + * @var SpreadsheetLoaderInterface[] + */ + protected $loaders = []; + + /** + * @var SpreadsheetLoader + */ + private static $workbookLoader; + + /** + * {@inheritdoc} + */ + public function open($path) + { + $type = $this->getType($path); + if (!isset($this->loaders[$type])) { + throw new InvalidArgumentException(sprintf('No loader for type %s', $type)); + } + + return $this->loaders[$type]->open($path); + } + + /** + * Addds a loader for a specified type + * + * @param string $type + * @param SpreadsheetLoaderInterface $loader + * + * @return SpreadsheetLoader + */ + public function addLoader($type, SpreadsheetLoaderInterface $loader) + { + $this->loaders[$type] = $loader; + } + + /** + * Returns the type for a path + * + * @param string $path + * + * @return string + */ + protected function getType($path) + { + return strtolower(pathinfo($path, PATHINFO_EXTENSION)); + } +} diff --git a/src/SpreadsheetParser.php b/src/SpreadsheetParser.php index d0dfe15..c7b501b 100644 --- a/src/SpreadsheetParser.php +++ b/src/SpreadsheetParser.php @@ -11,6 +11,11 @@ */ class SpreadsheetParser { + /** + * @var SpreadsheetLoader + */ + protected static $spreadsheetLoader; + /** * Opens a workbook * @@ -20,16 +25,26 @@ class SpreadsheetParser */ public static function open($path) { - return static::getXlsxSpreadsheetLoader()->open($path); + return static::getSpreadsheetLoader()->open($path); } /** - * Returns the XLSX workbook loader + * Returns the workbook loader * - * @return Xlsx\SpreadsheetLoader + * @return SpreadsheetLoaderInterface */ - public static function getXlsxSpreadsheetLoader() + public static function getSpreadsheetLoader() + { + if (!isset(static::$spreadsheetLoader)) { + static::$spreadsheetLoader = new SpreadsheetLoader(); + static::configureLoaders(); + } + } + + protected static function configureLoaders() { - return Xlsx\XlsxParser::getSpreadsheetLoader(); + static::$spreadsheetLoader + ->addLoader('xlsx', Xlsx\XlsxParser::getSpreadsheetLoader()) + ->addLoader('csv', Csv\CsvParser::getSpreadsheetLoader()); } } From 571b8ede12d453db91e6ab89d57b66e762682532 Mon Sep 17 00:00:00 2001 From: Antoine Guigan Date: Sat, 7 Jun 2014 10:54:41 +0200 Subject: [PATCH 07/22] Added unit tests for CSV --- .../SpreadsheetLoaderSpec.php | 8 +++- src/Csv/CsvParser.php | 8 +++- src/SpreadsheetLoader.php | 2 + src/SpreadsheetParser.php | 2 + tests/CsvTest.php | 39 +++++++++++++++++++ tests/fixtures/test.csv | 2 + 6 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 tests/CsvTest.php create mode 100644 tests/fixtures/test.csv diff --git a/spec/Akeneo/Component/SpreadsheetParser/SpreadsheetLoaderSpec.php b/spec/Akeneo/Component/SpreadsheetParser/SpreadsheetLoaderSpec.php index ef8e345..32136d1 100644 --- a/spec/Akeneo/Component/SpreadsheetParser/SpreadsheetLoaderSpec.php +++ b/spec/Akeneo/Component/SpreadsheetParser/SpreadsheetLoaderSpec.php @@ -13,9 +13,8 @@ public function let( SpreadsheetLoaderInterface $otherLoader, SpreadsheetInterface $spreadsheet ) { - $this->addLoader('extension', $loader); + $this->addLoader('extension', $loader)->addLoader('other_extension', $otherLoader); $loader->open('file.extension')->willReturn($spreadsheet); - $this->addLoader('other_extension', $otherLoader); } public function it_is_initializable() @@ -28,4 +27,9 @@ public function it_uses_the_loader_corresponding_to_the_file_extension( ) { $this->open('file.extension')->shouldReturn($spreadsheet); } + + public function it_throws_an_exception_if_no_loader_is_available() + { + $this->shouldThrow('\InvalidArgumentException')->duringOpen('file'); + } } diff --git a/src/Csv/CsvParser.php b/src/Csv/CsvParser.php index b4987d4..1ec19ea 100644 --- a/src/Csv/CsvParser.php +++ b/src/Csv/CsvParser.php @@ -19,6 +19,11 @@ class CsvParser */ const ROW_ITERATOR_CLASS = 'Akeneo\Component\SpreadsheetParser\Csv\RowIterator'; + /** + * @staticvar string The name of the sheet + */ + const SHEET_NAME = 'default'; + /** * @var SpreadsheetLoader */ @@ -44,7 +49,8 @@ public static function getSpreadsheetLoader() if (!isset(self::$workbookLoader)) { self::$workbookLoader = new SpreadsheetLoader( static::createRowIteratorFactory(), - static::WORKBOOK_CLASS + static::WORKBOOK_CLASS, + static::SHEET_NAME ); } diff --git a/src/SpreadsheetLoader.php b/src/SpreadsheetLoader.php index 5758cff..82fe2b5 100644 --- a/src/SpreadsheetLoader.php +++ b/src/SpreadsheetLoader.php @@ -47,6 +47,8 @@ public function open($path) public function addLoader($type, SpreadsheetLoaderInterface $loader) { $this->loaders[$type] = $loader; + + return $this; } /** diff --git a/src/SpreadsheetParser.php b/src/SpreadsheetParser.php index c7b501b..48da9d2 100644 --- a/src/SpreadsheetParser.php +++ b/src/SpreadsheetParser.php @@ -39,6 +39,8 @@ public static function getSpreadsheetLoader() static::$spreadsheetLoader = new SpreadsheetLoader(); static::configureLoaders(); } + + return static::$spreadsheetLoader; } protected static function configureLoaders() diff --git a/tests/CsvTest.php b/tests/CsvTest.php new file mode 100644 index 0000000..bf1161c --- /dev/null +++ b/tests/CsvTest.php @@ -0,0 +1,39 @@ + + * @copyright 2013 Akeneo SAS (http://www.akeneo.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +class CsvTest extends PHPUnit_Framework_TestCase +{ + public function testReadFile() + { + $workbook = SpreadsheetParser::open(__DIR__ . '/fixtures/test.csv'); + $this->assertEquals(['default'], $workbook->getWorksheets()); + $this->assertIteratesThrough( + [ + 0 => ['value', 'enclosed value', '15'], + 1 => ['', 'value2', ''] + ], + $workbook->createRowIterator(0) + ); + } + + protected function assertIteratesThrough($values, $iterator) + { + $valuesIterator = new ArrayIterator($values); + $valuesIterator->rewind(); + foreach ($iterator as $key => $row) { + $this->assertTrue($valuesIterator->valid()); + $this->assertEquals($valuesIterator->key(), $key); + $this->assertEquals($valuesIterator->current(), $row); + $valuesIterator->next(); + } + $this->assertFalse($valuesIterator->valid()); + } +} diff --git a/tests/fixtures/test.csv b/tests/fixtures/test.csv new file mode 100644 index 0000000..df62973 --- /dev/null +++ b/tests/fixtures/test.csv @@ -0,0 +1,2 @@ +value,"enclosed value",15 +,value2, \ No newline at end of file From 5f25a4fa211e987350980d804f13b1235a3aec0b Mon Sep 17 00:00:00 2001 From: Antoine Guigan Date: Sat, 7 Jun 2014 11:04:56 +0200 Subject: [PATCH 08/22] Added possibility to force format --- src/Csv/CsvParser.php | 5 +++++ src/SpreadsheetLoader.php | 9 ++------- src/SpreadsheetParser.php | 9 +++++---- src/Xlsx/XlsxParser.php | 5 +++++ tests/CsvTest.php | 14 ++++++++++++++ tests/fixtures/test.txt | 2 ++ 6 files changed, 33 insertions(+), 11 deletions(-) create mode 100644 tests/fixtures/test.txt diff --git a/src/Csv/CsvParser.php b/src/Csv/CsvParser.php index 1ec19ea..a1060eb 100644 --- a/src/Csv/CsvParser.php +++ b/src/Csv/CsvParser.php @@ -9,6 +9,11 @@ */ class CsvParser { + /** + * @staticvar string the name of the format + */ + const FORMAT_NAME = 'csv'; + /** * @staticvar string Spreadsheet class */ diff --git a/src/SpreadsheetLoader.php b/src/SpreadsheetLoader.php index 82fe2b5..d90c25a 100644 --- a/src/SpreadsheetLoader.php +++ b/src/SpreadsheetLoader.php @@ -18,17 +18,12 @@ class SpreadsheetLoader implements SpreadsheetLoaderInterface */ protected $loaders = []; - /** - * @var SpreadsheetLoader - */ - private static $workbookLoader; - /** * {@inheritdoc} */ - public function open($path) + public function open($path, $type = null) { - $type = $this->getType($path); + $type = $type ?: $this->getType($path); if (!isset($this->loaders[$type])) { throw new InvalidArgumentException(sprintf('No loader for type %s', $type)); } diff --git a/src/SpreadsheetParser.php b/src/SpreadsheetParser.php index 48da9d2..ed0e770 100644 --- a/src/SpreadsheetParser.php +++ b/src/SpreadsheetParser.php @@ -20,12 +20,13 @@ class SpreadsheetParser * Opens a workbook * * @param string $path + * @param string $type * * @return SpreadsheetInterface */ - public static function open($path) + public static function open($path, $type = null) { - return static::getSpreadsheetLoader()->open($path); + return static::getSpreadsheetLoader()->open($path, $type); } /** @@ -46,7 +47,7 @@ public static function getSpreadsheetLoader() protected static function configureLoaders() { static::$spreadsheetLoader - ->addLoader('xlsx', Xlsx\XlsxParser::getSpreadsheetLoader()) - ->addLoader('csv', Csv\CsvParser::getSpreadsheetLoader()); + ->addLoader(Xlsx\XlsxParser::FORMAT_NAME, Xlsx\XlsxParser::getSpreadsheetLoader()) + ->addLoader(Csv\CsvParser::FORMAT_NAME, Csv\CsvParser::getSpreadsheetLoader()); } } diff --git a/src/Xlsx/XlsxParser.php b/src/Xlsx/XlsxParser.php index 0e6d884..8a6291f 100644 --- a/src/Xlsx/XlsxParser.php +++ b/src/Xlsx/XlsxParser.php @@ -11,6 +11,11 @@ */ class XlsxParser { + /** + * @staticvar string the name of the format + */ + const FORMAT_NAME = 'xlsx'; + /** * @staticvar string Archive class */ diff --git a/tests/CsvTest.php b/tests/CsvTest.php index bf1161c..4f56314 100644 --- a/tests/CsvTest.php +++ b/tests/CsvTest.php @@ -1,5 +1,6 @@ assertEquals(['default'], $workbook->getWorksheets()); + $this->assertIteratesThrough( + [ + 0 => ['value', 'enclosed value', '15'], + 1 => ['', 'value2', ''] + ], + $workbook->createRowIterator(0) + ); + } + protected function assertIteratesThrough($values, $iterator) { $valuesIterator = new ArrayIterator($values); diff --git a/tests/fixtures/test.txt b/tests/fixtures/test.txt new file mode 100644 index 0000000..df62973 --- /dev/null +++ b/tests/fixtures/test.txt @@ -0,0 +1,2 @@ +value,"enclosed value",15 +,value2, \ No newline at end of file From ff516f9d96fb24fb9bb153a7e8bdfa5eff10b64a Mon Sep 17 00:00:00 2001 From: Antoine Guigan Date: Sat, 7 Jun 2014 11:05:51 +0200 Subject: [PATCH 09/22] Added doc --- src/SpreadsheetParser.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/SpreadsheetParser.php b/src/SpreadsheetParser.php index ed0e770..7fd6003 100644 --- a/src/SpreadsheetParser.php +++ b/src/SpreadsheetParser.php @@ -44,6 +44,9 @@ public static function getSpreadsheetLoader() return static::$spreadsheetLoader; } + /** + * Configure the loaders + */ protected static function configureLoaders() { static::$spreadsheetLoader From 1af0e6061a98d9bc613021f0356dc6485d8ce2f9 Mon Sep 17 00:00:00 2001 From: Antoine Guigan Date: Sat, 7 Jun 2014 11:12:32 +0200 Subject: [PATCH 10/22] Added functional tests --- tests/CsvTest.php | 12 ++++++++++++ tests/XlsxTest.php | 21 +++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/tests/CsvTest.php b/tests/CsvTest.php index 4f56314..688a063 100644 --- a/tests/CsvTest.php +++ b/tests/CsvTest.php @@ -38,6 +38,18 @@ public function testReadFileWithForcedFormat() ); } + public function testCsvParserClass() + { + $workbook = CsvParser::open(__DIR__ . '/fixtures/test.txt'); + $this->assertIteratesThrough( + [ + 0 => ['value', 'enclosed value', '15'], + 1 => ['', 'value2', ''] + ], + $workbook->createRowIterator(0) + ); + } + protected function assertIteratesThrough($values, $iterator) { $valuesIterator = new ArrayIterator($values); diff --git a/tests/XlsxTest.php b/tests/XlsxTest.php index 8af9a83..c2f3b25 100644 --- a/tests/XlsxTest.php +++ b/tests/XlsxTest.php @@ -1,6 +1,7 @@ assertEquals(['Sheet1', 'Sheet2'], $workbook->getWorksheets()); + $this->assertIteratesThrough( + [ + 2 => ['value1', '', 'value2'], + 3 => ['value3', '2010-12-05 00:00', 154], + 5 => ['test', '2006-08-12 15:46'] + ], + $workbook->createRowIterator(0) + ); + $this->assertIteratesThrough( + [ + 4 => ['value7', '', 'value11'] + ], + $workbook->createRowIterator(1) + ); + } + public function testReadSameFileTwice() { $workbook = SpreadsheetParser::open(__DIR__ . '/fixtures/libreoffice.xlsx'); From b4a9e33fd85f3e09484733a5a895dec51549fce9 Mon Sep 17 00:00:00 2001 From: Antoine Guigan Date: Sat, 7 Jun 2014 11:44:27 +0200 Subject: [PATCH 11/22] Code cleanup --- src/Xlsx/Relationships.php | 34 ++++++++++++---------------------- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/src/Xlsx/Relationships.php b/src/Xlsx/Relationships.php index 0e8253a..76db731 100644 --- a/src/Xlsx/Relationships.php +++ b/src/Xlsx/Relationships.php @@ -41,12 +41,20 @@ class Relationships extends AbstractXMLResource * * @param string $relationshipsPath the path to the XML relationships file */ - public function __construct($relationshipsPath) + public function __construct($path) { - parent::__construct($relationshipsPath); - $this->relationshipsPath = $relationshipsPath; + parent::__construct($path); + $xml = $this->getXMLReader(); - $this->readRelationShips(); + while ($xml->read()) { + if (\XMLReader::ELEMENT === $xml->nodeType && 'Relationship' === $xml->name) { + + $type = basename((string) $xml->getAttribute('Type')); + $this->storeRelationShipByType($type, $xml->getAttribute('Id'), 'xl/' . $xml->getAttribute('Target')); + } + } + + $this->closeXMLReader(); } /** @@ -81,24 +89,6 @@ public function getStylesPath() return $this->stylePath; } - /** - * Reads the entire relationShips file once - */ - private function readRelationShips() - { - $xml = $this->getXMLReader($this->relationshipsPath); - - while ($xml->read()) { - if (\XMLReader::ELEMENT === $xml->nodeType && 'Relationship' === $xml->name) { - - $type = basename((string) $xml->getAttribute('Type')); - $this->storeRelationShipByType($type, $xml->getAttribute('Id'), 'xl/' . $xml->getAttribute('Target')); - } - } - - $this->closeXMLReader(); - } - /** * stores the relationShip into the right variable * From 4093a3619e63ad0acbc565892579333349363eae Mon Sep 17 00:00:00 2001 From: Antoine Guigan Date: Sat, 7 Jun 2014 11:53:15 +0200 Subject: [PATCH 12/22] Code cleanup --- src/Csv/RowIterator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Csv/RowIterator.php b/src/Csv/RowIterator.php index ac75b32..748837a 100644 --- a/src/Csv/RowIterator.php +++ b/src/Csv/RowIterator.php @@ -29,7 +29,7 @@ class RowIterator implements \Iterator protected $options; /** - * @var int + * @var resource */ protected $fileHandle; From 031652f74423e446b26f556b5018ee843be40384 Mon Sep 17 00:00:00 2001 From: Antoine Guigan Date: Sat, 7 Jun 2014 11:58:19 +0200 Subject: [PATCH 13/22] Fixed PHPDOC --- src/SpreadsheetLoader.php | 9 ++++++++- src/Xlsx/ColumnIndexTransformer.php | 2 +- src/Xlsx/Relationships.php | 2 +- src/Xlsx/RowBuilderFactory.php | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/SpreadsheetLoader.php b/src/SpreadsheetLoader.php index d90c25a..0f2740b 100644 --- a/src/SpreadsheetLoader.php +++ b/src/SpreadsheetLoader.php @@ -19,7 +19,14 @@ class SpreadsheetLoader implements SpreadsheetLoaderInterface protected $loaders = []; /** - * {@inheritdoc} + * Opens a workbook + * + * @param string $path + * @param string $type + * + * @return SpreadsheetInterface + * + * @throws InvalidArgumentException */ public function open($path, $type = null) { diff --git a/src/Xlsx/ColumnIndexTransformer.php b/src/Xlsx/ColumnIndexTransformer.php index 3bddf3e..c2973c7 100644 --- a/src/Xlsx/ColumnIndexTransformer.php +++ b/src/Xlsx/ColumnIndexTransformer.php @@ -17,7 +17,7 @@ class ColumnIndexTransformer * * @param string $name * - * @return string + * @return integer */ public function transform($name) { diff --git a/src/Xlsx/Relationships.php b/src/Xlsx/Relationships.php index 76db731..2b1f6e0 100644 --- a/src/Xlsx/Relationships.php +++ b/src/Xlsx/Relationships.php @@ -39,7 +39,7 @@ class Relationships extends AbstractXMLResource /** * Constructor * - * @param string $relationshipsPath the path to the XML relationships file + * @param string $path the path to the XML relationships file */ public function __construct($path) { diff --git a/src/Xlsx/RowBuilderFactory.php b/src/Xlsx/RowBuilderFactory.php index 2ceb13b..664906c 100644 --- a/src/Xlsx/RowBuilderFactory.php +++ b/src/Xlsx/RowBuilderFactory.php @@ -22,7 +22,7 @@ class RowBuilderFactory /** * Constructor * - * @param string $className + * @param string $rowBuilderClass */ public function __construct($rowBuilderClass) { From abc600acb833b137b786ea51fc4ca887b3c40744 Mon Sep 17 00:00:00 2001 From: Antoine Guigan Date: Sat, 7 Jun 2014 20:44:44 +0200 Subject: [PATCH 14/22] Added PHP version dependency --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index 7e201a6..1fb946d 100644 --- a/composer.json +++ b/composer.json @@ -17,6 +17,7 @@ } ], "require": { + "php": ">=5.4.0", "symfony/options-resolver": "2.*" }, "require-dev": { From 8e0c1c936392e24f768c0b6ef531eff38dc7d43f Mon Sep 17 00:00:00 2001 From: Antoine Guigan Date: Mon, 9 Jun 2014 07:23:12 +0200 Subject: [PATCH 15/22] Added instructions for running tests --- README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/README.md b/README.md index d1741c5..cc1e4d1 100644 --- a/README.md +++ b/README.md @@ -31,3 +31,18 @@ To extract data from a spreadsheet, use the following code: foreach ($workbook->createIterator($myWorksheetIndex) as $rowIndex => $values) { var_dump($rowIndex, $values); } + + +Running the tests +----------------- + +To run unit tests, use phpspec: + + $ php bin/phpspec run + + +To run integration tests, use phpunit: + + $ phpunit + + From 2280c0e6ea91255dd6f50813e097da8279163b96 Mon Sep 17 00:00:00 2001 From: Antoine Guigan Date: Mon, 9 Jun 2014 10:22:21 +0200 Subject: [PATCH 16/22] Added decoding in CSV parser --- .../SpreadsheetParser/Csv/RowIteratorSpec.php | 19 ++++++++++ .../Csv/fixtures/iso-8859-15.csv | 1 + src/Csv/RowIterator.php | 35 ++++++++++++++++++- 3 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 spec/Akeneo/Component/SpreadsheetParser/Csv/fixtures/iso-8859-15.csv diff --git a/spec/Akeneo/Component/SpreadsheetParser/Csv/RowIteratorSpec.php b/spec/Akeneo/Component/SpreadsheetParser/Csv/RowIteratorSpec.php index df47d84..215d5d4 100644 --- a/spec/Akeneo/Component/SpreadsheetParser/Csv/RowIteratorSpec.php +++ b/spec/Akeneo/Component/SpreadsheetParser/Csv/RowIteratorSpec.php @@ -58,4 +58,23 @@ public function it_accepts_options() } $this->valid()->shouldReturn(false); } + + public function it_converts_between_encodings() + { + $this->beConstructedWith( + __DIR__ . '/fixtures/iso-8859-15.csv', + [ + 'encoding' => 'iso-8859-15' + ] + ); + $values = [['é', 'è', '€']]; + $this->rewind(); + foreach ($values as $i => $row) { + $this->key()->shouldReturn($i); + $this->valid()->shouldReturn(true); + $this->current()->shouldReturn($row); + $this->next(); + } + $this->valid()->shouldReturn(false); + } } diff --git a/spec/Akeneo/Component/SpreadsheetParser/Csv/fixtures/iso-8859-15.csv b/spec/Akeneo/Component/SpreadsheetParser/Csv/fixtures/iso-8859-15.csv new file mode 100644 index 0000000..ea41ae8 --- /dev/null +++ b/spec/Akeneo/Component/SpreadsheetParser/Csv/fixtures/iso-8859-15.csv @@ -0,0 +1 @@ +é,è,¤ diff --git a/src/Csv/RowIterator.php b/src/Csv/RowIterator.php index 748837a..895e32f 100644 --- a/src/Csv/RowIterator.php +++ b/src/Csv/RowIterator.php @@ -104,7 +104,7 @@ public function rewind() if ($this->fileHandle) { rewind($this->fileHandle); } else { - $this->fileHandle = fopen($this->path, 'r'); + $this->openResource(); } $this->currentKey = -1; $this->next(); @@ -125,6 +125,7 @@ public function valid() */ protected function setDefaultOptions(OptionsResolverInterface $resolver) { + $resolver->setOptional(['encoding']); $resolver->setDefaults( [ 'length' => null, @@ -134,4 +135,36 @@ protected function setDefaultOptions(OptionsResolverInterface $resolver) ] ); } + + /** + * Opens the file resource + * + * @return resource + */ + protected function openResource() + { + $this->fileHandle = fopen($this->path, 'r'); + if (isset($this->options['encoding'])) { + stream_filter_prepend( + $this->fileHandle, + sprintf( + "convert.iconv.%s/%s", + $this->options['encoding'], + $this->getCurrentEncoding() + ) + ); + } + } + + /** + * Returns the server encoding + * + * @return string + */ + protected function getCurrentEncoding() + { + $locale = explode('.', setlocale(LC_CTYPE, 0)); + + return isset($locale[1]) ? $locale[1] : 'ASCII'; + } } From 287b832f0508fa452675199a9c3aff0e9e52e53c Mon Sep 17 00:00:00 2001 From: Antoine Guigan Date: Mon, 9 Jun 2014 10:35:01 +0200 Subject: [PATCH 17/22] Cleaned up fixtures --- .../SpreadsheetParser/Xlsx/ArchiveSpec.php | 2 +- .../SpreadsheetParser/Xlsx/RelationshipsSpec.php | 2 +- .../SpreadsheetParser/Xlsx/RowIteratorSpec.php | 2 +- .../SpreadsheetParser/Xlsx/SharedStringsSpec.php | 2 +- .../Component/SpreadsheetParser/Xlsx/StylesSpec.php | 2 +- .../Xlsx/WorksheetListReaderSpec.php | 2 +- .../{ => Xlsx}/fixtures/sharedStrings.xml | 0 .../SpreadsheetParser/{ => Xlsx}/fixtures/sheet.xml | 0 .../{ => Xlsx}/fixtures/styles.xml | 0 .../SpreadsheetParser/{ => Xlsx}/fixtures/test.zip | Bin .../{ => Xlsx}/fixtures/workbook.xml | 0 .../{ => Xlsx}/fixtures/workbook.xml.rels | 0 .../fixtures/excel_2003_footer.txt | 1 - .../fixtures/excel_2003_header.txt | 1 - 14 files changed, 6 insertions(+), 8 deletions(-) rename spec/Akeneo/Component/SpreadsheetParser/{ => Xlsx}/fixtures/sharedStrings.xml (100%) rename spec/Akeneo/Component/SpreadsheetParser/{ => Xlsx}/fixtures/sheet.xml (100%) rename spec/Akeneo/Component/SpreadsheetParser/{ => Xlsx}/fixtures/styles.xml (100%) rename spec/Akeneo/Component/SpreadsheetParser/{ => Xlsx}/fixtures/test.zip (100%) rename spec/Akeneo/Component/SpreadsheetParser/{ => Xlsx}/fixtures/workbook.xml (100%) rename spec/Akeneo/Component/SpreadsheetParser/{ => Xlsx}/fixtures/workbook.xml.rels (100%) delete mode 100644 spec/Akeneo/Component/SpreadsheetParser/fixtures/excel_2003_footer.txt delete mode 100644 spec/Akeneo/Component/SpreadsheetParser/fixtures/excel_2003_header.txt diff --git a/spec/Akeneo/Component/SpreadsheetParser/Xlsx/ArchiveSpec.php b/spec/Akeneo/Component/SpreadsheetParser/Xlsx/ArchiveSpec.php index 7c2c119..07707d8 100644 --- a/spec/Akeneo/Component/SpreadsheetParser/Xlsx/ArchiveSpec.php +++ b/spec/Akeneo/Component/SpreadsheetParser/Xlsx/ArchiveSpec.php @@ -8,7 +8,7 @@ class ArchiveSpec extends ObjectBehavior { public function let() { - $this->beConstructedWith(__DIR__ . '/../fixtures/test.zip'); + $this->beConstructedWith(__DIR__ . '/fixtures/test.zip'); } public function it_is_initializable() diff --git a/spec/Akeneo/Component/SpreadsheetParser/Xlsx/RelationshipsSpec.php b/spec/Akeneo/Component/SpreadsheetParser/Xlsx/RelationshipsSpec.php index d5c74a3..2fd6cab 100644 --- a/spec/Akeneo/Component/SpreadsheetParser/Xlsx/RelationshipsSpec.php +++ b/spec/Akeneo/Component/SpreadsheetParser/Xlsx/RelationshipsSpec.php @@ -8,7 +8,7 @@ class RelationshipsSpec extends ObjectBehavior { public function let() { - $this->beConstructedWith(__DIR__ . '/../fixtures/workbook.xml.rels'); + $this->beConstructedWith(__DIR__ . '/fixtures/workbook.xml.rels'); } public function it_is_initializable() diff --git a/spec/Akeneo/Component/SpreadsheetParser/Xlsx/RowIteratorSpec.php b/spec/Akeneo/Component/SpreadsheetParser/Xlsx/RowIteratorSpec.php index 346c82b..25982f3 100644 --- a/spec/Akeneo/Component/SpreadsheetParser/Xlsx/RowIteratorSpec.php +++ b/spec/Akeneo/Component/SpreadsheetParser/Xlsx/RowIteratorSpec.php @@ -50,7 +50,7 @@ function () use (&$row) { $rowBuilderFactory, $columnIndexTransformer, $valueTransformer, - __DIR__ . '/../fixtures/sheet.xml', + __DIR__ . '/fixtures/sheet.xml', [] ); $valueTransformer->transform(Argument::type('string'),Argument::type('string'),Argument::type('string'))->will( diff --git a/spec/Akeneo/Component/SpreadsheetParser/Xlsx/SharedStringsSpec.php b/spec/Akeneo/Component/SpreadsheetParser/Xlsx/SharedStringsSpec.php index b5c20f6..e951fb3 100644 --- a/spec/Akeneo/Component/SpreadsheetParser/Xlsx/SharedStringsSpec.php +++ b/spec/Akeneo/Component/SpreadsheetParser/Xlsx/SharedStringsSpec.php @@ -8,7 +8,7 @@ class SharedStringsSpec extends ObjectBehavior { public function let() { - $this->beConstructedWith(__DIR__ . '/../fixtures/sharedStrings.xml'); + $this->beConstructedWith(__DIR__ . '/fixtures/sharedStrings.xml'); } public function it_is_initializable() diff --git a/spec/Akeneo/Component/SpreadsheetParser/Xlsx/StylesSpec.php b/spec/Akeneo/Component/SpreadsheetParser/Xlsx/StylesSpec.php index ceb0305..cf7f56d 100644 --- a/spec/Akeneo/Component/SpreadsheetParser/Xlsx/StylesSpec.php +++ b/spec/Akeneo/Component/SpreadsheetParser/Xlsx/StylesSpec.php @@ -9,7 +9,7 @@ class StylesSpec extends ObjectBehavior { public function let() { - $this->beConstructedWith(__DIR__ . '/../fixtures/styles.xml'); + $this->beConstructedWith(__DIR__ . '/fixtures/styles.xml'); } public function it_is_initializable() diff --git a/spec/Akeneo/Component/SpreadsheetParser/Xlsx/WorksheetListReaderSpec.php b/spec/Akeneo/Component/SpreadsheetParser/Xlsx/WorksheetListReaderSpec.php index a19fab1..dc6a48b 100644 --- a/spec/Akeneo/Component/SpreadsheetParser/Xlsx/WorksheetListReaderSpec.php +++ b/spec/Akeneo/Component/SpreadsheetParser/Xlsx/WorksheetListReaderSpec.php @@ -19,7 +19,7 @@ function ($args) { return 'file_' . $args[0]; } ); - $this->getWorksheetPaths($relationships, __DIR__ . '/../fixtures/workbook.xml')->shouldReturn( + $this->getWorksheetPaths($relationships, __DIR__ . '/fixtures/workbook.xml')->shouldReturn( [ 'Worksheet1' => 'file_rId2', 'Worksheet2' => 'file_rId3', diff --git a/spec/Akeneo/Component/SpreadsheetParser/fixtures/sharedStrings.xml b/spec/Akeneo/Component/SpreadsheetParser/Xlsx/fixtures/sharedStrings.xml similarity index 100% rename from spec/Akeneo/Component/SpreadsheetParser/fixtures/sharedStrings.xml rename to spec/Akeneo/Component/SpreadsheetParser/Xlsx/fixtures/sharedStrings.xml diff --git a/spec/Akeneo/Component/SpreadsheetParser/fixtures/sheet.xml b/spec/Akeneo/Component/SpreadsheetParser/Xlsx/fixtures/sheet.xml similarity index 100% rename from spec/Akeneo/Component/SpreadsheetParser/fixtures/sheet.xml rename to spec/Akeneo/Component/SpreadsheetParser/Xlsx/fixtures/sheet.xml diff --git a/spec/Akeneo/Component/SpreadsheetParser/fixtures/styles.xml b/spec/Akeneo/Component/SpreadsheetParser/Xlsx/fixtures/styles.xml similarity index 100% rename from spec/Akeneo/Component/SpreadsheetParser/fixtures/styles.xml rename to spec/Akeneo/Component/SpreadsheetParser/Xlsx/fixtures/styles.xml diff --git a/spec/Akeneo/Component/SpreadsheetParser/fixtures/test.zip b/spec/Akeneo/Component/SpreadsheetParser/Xlsx/fixtures/test.zip similarity index 100% rename from spec/Akeneo/Component/SpreadsheetParser/fixtures/test.zip rename to spec/Akeneo/Component/SpreadsheetParser/Xlsx/fixtures/test.zip diff --git a/spec/Akeneo/Component/SpreadsheetParser/fixtures/workbook.xml b/spec/Akeneo/Component/SpreadsheetParser/Xlsx/fixtures/workbook.xml similarity index 100% rename from spec/Akeneo/Component/SpreadsheetParser/fixtures/workbook.xml rename to spec/Akeneo/Component/SpreadsheetParser/Xlsx/fixtures/workbook.xml diff --git a/spec/Akeneo/Component/SpreadsheetParser/fixtures/workbook.xml.rels b/spec/Akeneo/Component/SpreadsheetParser/Xlsx/fixtures/workbook.xml.rels similarity index 100% rename from spec/Akeneo/Component/SpreadsheetParser/fixtures/workbook.xml.rels rename to spec/Akeneo/Component/SpreadsheetParser/Xlsx/fixtures/workbook.xml.rels diff --git a/spec/Akeneo/Component/SpreadsheetParser/fixtures/excel_2003_footer.txt b/spec/Akeneo/Component/SpreadsheetParser/fixtures/excel_2003_footer.txt deleted file mode 100644 index 588ad7e..0000000 --- a/spec/Akeneo/Component/SpreadsheetParser/fixtures/excel_2003_footer.txt +++ /dev/null @@ -1 +0,0 @@ -FOOTER \ No newline at end of file diff --git a/spec/Akeneo/Component/SpreadsheetParser/fixtures/excel_2003_header.txt b/spec/Akeneo/Component/SpreadsheetParser/fixtures/excel_2003_header.txt deleted file mode 100644 index a5bcc79..0000000 --- a/spec/Akeneo/Component/SpreadsheetParser/fixtures/excel_2003_header.txt +++ /dev/null @@ -1 +0,0 @@ -HEADER From fbd16a309101bd247d267c968a7dc0a312ca4f33 Mon Sep 17 00:00:00 2001 From: Antoine Guigan Date: Mon, 9 Jun 2014 10:40:34 +0200 Subject: [PATCH 18/22] Corrected PHPDoc --- README.md | 27 ++++++++++++++++++++++++++- src/Csv/RowIterator.php | 11 +++++++---- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index cc1e4d1..0a61e8d 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ From your application root: Usage ----- -To extract data from a spreadsheet, use the following code: +To extract data from an XLSX spreadsheet, use the following code: createIterator( + 0, + [ + 'encoding' => 'UTF-8', + 'length' => null, + 'delimiter' => ',', + 'enclosure' => '"', + 'escape' => '\\' + ] + ); + + + foreach ($workbook->createIterator($myWorksheetIndex) as $rowIndex => $values) { + var_dump($rowIndex, $values); + } + + Running the tests ----------------- diff --git a/src/Csv/RowIterator.php b/src/Csv/RowIterator.php index 895e32f..528b979 100644 --- a/src/Csv/RowIterator.php +++ b/src/Csv/RowIterator.php @@ -6,11 +6,14 @@ use Symfony\Component\OptionsResolver\OptionsResolverInterface; /** - * Row iterator for an Excel worksheet + * Row iterator for CSV * - * The iterator returns arrays of results. - * - * Empty values are trimed from the right of the rows, and empty rows are skipped. + * The following options are available : + * - length: the maximum length of read lines + * - delimiter: the CSV delimiter character + * - enclosure: the CSV enclosure character + * - escape: the CSV escape character + * - encoding: the encoding of the CSV file * * @author Antoine Guigan * @copyright 2013 Akeneo SAS (http://www.akeneo.com) From a438e458f6e1c1d6b7de50149c3a1b021aa55325 Mon Sep 17 00:00:00 2001 From: Antoine Guigan Date: Mon, 9 Jun 2014 10:41:34 +0200 Subject: [PATCH 19/22] Corrected copyright date --- src/Csv/RowIterator.php | 2 +- src/Csv/RowIteratorFactory.php | 2 +- src/Csv/Spreadsheet.php | 2 +- src/Csv/SpreadsheetLoader.php | 2 +- src/SpreadsheetInterface.php | 2 +- src/SpreadsheetLoader.php | 2 +- src/SpreadsheetLoaderInterface.php | 2 +- src/SpreadsheetParser.php | 2 +- src/Xlsx/AbstractXMLDictionnary.php | 2 +- src/Xlsx/AbstractXMLResource.php | 2 +- src/Xlsx/Archive.php | 2 +- src/Xlsx/ArchiveLoader.php | 2 +- src/Xlsx/ColumnIndexTransformer.php | 2 +- src/Xlsx/DateTransformer.php | 2 +- src/Xlsx/Relationships.php | 2 +- src/Xlsx/RelationshipsLoader.php | 2 +- src/Xlsx/RowBuilder.php | 2 +- src/Xlsx/RowBuilderFactory.php | 2 +- src/Xlsx/RowIterator.php | 2 +- src/Xlsx/RowIteratorFactory.php | 2 +- src/Xlsx/SharedStrings.php | 2 +- src/Xlsx/SharedStringsLoader.php | 2 +- src/Xlsx/Spreadsheet.php | 2 +- src/Xlsx/SpreadsheetLoader.php | 2 +- src/Xlsx/Styles.php | 2 +- src/Xlsx/StylesLoader.php | 2 +- src/Xlsx/ValueTransformer.php | 2 +- src/Xlsx/ValueTransformerFactory.php | 2 +- src/Xlsx/WorksheetListReader.php | 2 +- src/Xlsx/XlsxParser.php | 2 +- tests/CsvTest.php | 2 +- tests/XlsxTest.php | 2 +- 32 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/Csv/RowIterator.php b/src/Csv/RowIterator.php index 528b979..ae30a37 100644 --- a/src/Csv/RowIterator.php +++ b/src/Csv/RowIterator.php @@ -16,7 +16,7 @@ * - encoding: the encoding of the CSV file * * @author Antoine Guigan - * @copyright 2013 Akeneo SAS (http://www.akeneo.com) + * @copyright 2014 Akeneo SAS (http://www.akeneo.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ class RowIterator implements \Iterator diff --git a/src/Csv/RowIteratorFactory.php b/src/Csv/RowIteratorFactory.php index 64364de..c8f3ddd 100644 --- a/src/Csv/RowIteratorFactory.php +++ b/src/Csv/RowIteratorFactory.php @@ -6,7 +6,7 @@ * Row iterator factory * * @author Antoine Guigan - * @copyright 2013 Akeneo SAS (http://www.akeneo.com) + * @copyright 2014 Akeneo SAS (http://www.akeneo.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ class RowIteratorFactory diff --git a/src/Csv/Spreadsheet.php b/src/Csv/Spreadsheet.php index e14442a..31a68ca 100644 --- a/src/Csv/Spreadsheet.php +++ b/src/Csv/Spreadsheet.php @@ -8,7 +8,7 @@ * Represents a CSV workbook * * @author Antoine Guigan - * @copyright 2013 Akeneo SAS (http://www.akeneo.com) + * @copyright 2014 Akeneo SAS (http://www.akeneo.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ class Spreadsheet implements SpreadsheetInterface diff --git a/src/Csv/SpreadsheetLoader.php b/src/Csv/SpreadsheetLoader.php index 04ee65e..2c9ac57 100644 --- a/src/Csv/SpreadsheetLoader.php +++ b/src/Csv/SpreadsheetLoader.php @@ -8,7 +8,7 @@ * CSV file reader * * @author Antoine Guigan - * @copyright 2013 Akeneo SAS (http://www.akeneo.com) + * @copyright 2014 Akeneo SAS (http://www.akeneo.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ class SpreadsheetLoader implements SpreadsheetLoaderInterface diff --git a/src/SpreadsheetInterface.php b/src/SpreadsheetInterface.php index f618897..76849e7 100644 --- a/src/SpreadsheetInterface.php +++ b/src/SpreadsheetInterface.php @@ -6,7 +6,7 @@ * Common interface for workbooks * * @author Antoine Guigan - * @copyright 2013 Akeneo SAS (http://www.akeneo.com) + * @copyright 2014 Akeneo SAS (http://www.akeneo.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ interface SpreadsheetInterface diff --git a/src/SpreadsheetLoader.php b/src/SpreadsheetLoader.php index 0f2740b..635c369 100644 --- a/src/SpreadsheetLoader.php +++ b/src/SpreadsheetLoader.php @@ -8,7 +8,7 @@ * Format agnostic spreadsheet loader * * @author Antoine Guigan - * @copyright 2013 Akeneo SAS (http://www.akeneo.com) + * @copyright 2014 Akeneo SAS (http://www.akeneo.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ class SpreadsheetLoader implements SpreadsheetLoaderInterface diff --git a/src/SpreadsheetLoaderInterface.php b/src/SpreadsheetLoaderInterface.php index f26f393..1a70c10 100644 --- a/src/SpreadsheetLoaderInterface.php +++ b/src/SpreadsheetLoaderInterface.php @@ -6,7 +6,7 @@ * Common interface for workbook loaders * * @author Antoine Guigan - * @copyright 2013 Akeneo SAS (http://www.akeneo.com) + * @copyright 2014 Akeneo SAS (http://www.akeneo.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ interface SpreadsheetLoaderInterface diff --git a/src/SpreadsheetParser.php b/src/SpreadsheetParser.php index 7fd6003..20e748f 100644 --- a/src/SpreadsheetParser.php +++ b/src/SpreadsheetParser.php @@ -6,7 +6,7 @@ * Entry point for the SpreadsheetParser component * * @author Antoine Guigan - * @copyright 2013 Akeneo SAS (http://www.akeneo.com) + * @copyright 2014 Akeneo SAS (http://www.akeneo.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ class SpreadsheetParser diff --git a/src/Xlsx/AbstractXMLDictionnary.php b/src/Xlsx/AbstractXMLDictionnary.php index a71ff0b..a820c6b 100644 --- a/src/Xlsx/AbstractXMLDictionnary.php +++ b/src/Xlsx/AbstractXMLDictionnary.php @@ -6,7 +6,7 @@ * Base class for XML dictionnary resources * * @author Antoine Guigan - * @copyright 2013 Akeneo SAS (http://www.akeneo.com) + * @copyright 2014 Akeneo SAS (http://www.akeneo.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ abstract class AbstractXMLDictionnary extends AbstractXMLResource diff --git a/src/Xlsx/AbstractXMLResource.php b/src/Xlsx/AbstractXMLResource.php index 0f8e2ca..cf83dc4 100644 --- a/src/Xlsx/AbstractXMLResource.php +++ b/src/Xlsx/AbstractXMLResource.php @@ -6,7 +6,7 @@ * Base class for single files XML resources * * @author Antoine Guigan - * @copyright 2013 Akeneo SAS (http://www.akeneo.com) + * @copyright 2014 Akeneo SAS (http://www.akeneo.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ abstract class AbstractXMLResource diff --git a/src/Xlsx/Archive.php b/src/Xlsx/Archive.php index 59d5ae2..842125a 100644 --- a/src/Xlsx/Archive.php +++ b/src/Xlsx/Archive.php @@ -6,7 +6,7 @@ * Represents an XLSX Archive * * @author Antoine Guigan - * @copyright 2013 Akeneo SAS (http://www.akeneo.com) + * @copyright 2014 Akeneo SAS (http://www.akeneo.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ class Archive diff --git a/src/Xlsx/ArchiveLoader.php b/src/Xlsx/ArchiveLoader.php index 42c8937..d9fc0b8 100644 --- a/src/Xlsx/ArchiveLoader.php +++ b/src/Xlsx/ArchiveLoader.php @@ -6,7 +6,7 @@ * XLSX archive loader * * @author Antoine Guigan - * @copyright 2013 Akeneo SAS (http://www.akeneo.com) + * @copyright 2014 Akeneo SAS (http://www.akeneo.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ class ArchiveLoader diff --git a/src/Xlsx/ColumnIndexTransformer.php b/src/Xlsx/ColumnIndexTransformer.php index c2973c7..da5fac9 100644 --- a/src/Xlsx/ColumnIndexTransformer.php +++ b/src/Xlsx/ColumnIndexTransformer.php @@ -6,7 +6,7 @@ * Transforms an Excel cell name in an index * * @author Antoine Guigan - * @copyright 2013 Akeneo SAS (http://www.akeneo.com) + * @copyright 2014 Akeneo SAS (http://www.akeneo.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ diff --git a/src/Xlsx/DateTransformer.php b/src/Xlsx/DateTransformer.php index 8cd9331..7a6781f 100644 --- a/src/Xlsx/DateTransformer.php +++ b/src/Xlsx/DateTransformer.php @@ -6,7 +6,7 @@ * Transforms Excel dates in DateTime objects * * @author Antoine Guigan - * @copyright 2013 Akeneo SAS (http://www.akeneo.com) + * @copyright 2014 Akeneo SAS (http://www.akeneo.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ class DateTransformer diff --git a/src/Xlsx/Relationships.php b/src/Xlsx/Relationships.php index 2b1f6e0..280ef99 100644 --- a/src/Xlsx/Relationships.php +++ b/src/Xlsx/Relationships.php @@ -6,7 +6,7 @@ * Spreadsheet relationships * * @author Antoine Guigan - * @copyright 2013 Akeneo SAS (http://www.akeneo.com) + * @copyright 2014 Akeneo SAS (http://www.akeneo.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ class Relationships extends AbstractXMLResource diff --git a/src/Xlsx/RelationshipsLoader.php b/src/Xlsx/RelationshipsLoader.php index 58aae20..594c1a6 100644 --- a/src/Xlsx/RelationshipsLoader.php +++ b/src/Xlsx/RelationshipsLoader.php @@ -6,7 +6,7 @@ * Relationships loader * * @author Antoine Guigan - * @copyright 2013 Akeneo SAS (http://www.akeneo.com) + * @copyright 2014 Akeneo SAS (http://www.akeneo.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ class RelationshipsLoader diff --git a/src/Xlsx/RowBuilder.php b/src/Xlsx/RowBuilder.php index 4c9c171..5b86c99 100644 --- a/src/Xlsx/RowBuilder.php +++ b/src/Xlsx/RowBuilder.php @@ -6,7 +6,7 @@ * Builds a row with skipped values * * @author Antoine Guigan - * @copyright 2013 Akeneo SAS (http://www.akeneo.com) + * @copyright 2014 Akeneo SAS (http://www.akeneo.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ class RowBuilder diff --git a/src/Xlsx/RowBuilderFactory.php b/src/Xlsx/RowBuilderFactory.php index 664906c..7c53785 100644 --- a/src/Xlsx/RowBuilderFactory.php +++ b/src/Xlsx/RowBuilderFactory.php @@ -6,7 +6,7 @@ * Factory for RowBuilder objects * * @author Antoine Guigan - * @copyright 2013 Akeneo SAS (http://www.akeneo.com) + * @copyright 2014 Akeneo SAS (http://www.akeneo.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ diff --git a/src/Xlsx/RowIterator.php b/src/Xlsx/RowIterator.php index 31d16ed..58c6103 100644 --- a/src/Xlsx/RowIterator.php +++ b/src/Xlsx/RowIterator.php @@ -10,7 +10,7 @@ * Empty values are trimed from the right of the rows, and empty rows are skipped. * * @author Antoine Guigan - * @copyright 2013 Akeneo SAS (http://www.akeneo.com) + * @copyright 2014 Akeneo SAS (http://www.akeneo.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ class RowIterator implements \Iterator diff --git a/src/Xlsx/RowIteratorFactory.php b/src/Xlsx/RowIteratorFactory.php index e2c3928..99c6aa7 100644 --- a/src/Xlsx/RowIteratorFactory.php +++ b/src/Xlsx/RowIteratorFactory.php @@ -6,7 +6,7 @@ * Row iterator factory * * @author Antoine Guigan - * @copyright 2013 Akeneo SAS (http://www.akeneo.com) + * @copyright 2014 Akeneo SAS (http://www.akeneo.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ class RowIteratorFactory diff --git a/src/Xlsx/SharedStrings.php b/src/Xlsx/SharedStrings.php index 9a26ca6..ff2a978 100644 --- a/src/Xlsx/SharedStrings.php +++ b/src/Xlsx/SharedStrings.php @@ -6,7 +6,7 @@ * Contains the shared strings of an Excel workbook * * @author Antoine Guigan - * @copyright 2013 Akeneo SAS (http://www.akeneo.com) + * @copyright 2014 Akeneo SAS (http://www.akeneo.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ class SharedStrings extends AbstractXMLDictionnary diff --git a/src/Xlsx/SharedStringsLoader.php b/src/Xlsx/SharedStringsLoader.php index 6001e85..3a04c7a 100644 --- a/src/Xlsx/SharedStringsLoader.php +++ b/src/Xlsx/SharedStringsLoader.php @@ -6,7 +6,7 @@ * SharedStrings factory * * @author Antoine Guigan - * @copyright 2013 Akeneo SAS (http://www.akeneo.com) + * @copyright 2014 Akeneo SAS (http://www.akeneo.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ class SharedStringsLoader diff --git a/src/Xlsx/Spreadsheet.php b/src/Xlsx/Spreadsheet.php index eebc7b7..b71b16a 100644 --- a/src/Xlsx/Spreadsheet.php +++ b/src/Xlsx/Spreadsheet.php @@ -8,7 +8,7 @@ * Represents an XLSX workbook * * @author Antoine Guigan - * @copyright 2013 Akeneo SAS (http://www.akeneo.com) + * @copyright 2014 Akeneo SAS (http://www.akeneo.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ class Spreadsheet implements SpreadsheetInterface diff --git a/src/Xlsx/SpreadsheetLoader.php b/src/Xlsx/SpreadsheetLoader.php index 4feb54c..69efed0 100644 --- a/src/Xlsx/SpreadsheetLoader.php +++ b/src/Xlsx/SpreadsheetLoader.php @@ -8,7 +8,7 @@ * XLSX file reader * * @author Antoine Guigan - * @copyright 2013 Akeneo SAS (http://www.akeneo.com) + * @copyright 2014 Akeneo SAS (http://www.akeneo.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ class SpreadsheetLoader implements SpreadsheetLoaderInterface diff --git a/src/Xlsx/Styles.php b/src/Xlsx/Styles.php index 15586a1..99f673d 100644 --- a/src/Xlsx/Styles.php +++ b/src/Xlsx/Styles.php @@ -6,7 +6,7 @@ * Spreadsheet styles * * @author Antoine Guigan - * @copyright 2013 Akeneo SAS (http://www.akeneo.com) + * @copyright 2014 Akeneo SAS (http://www.akeneo.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ class Styles extends AbstractXMLDictionnary diff --git a/src/Xlsx/StylesLoader.php b/src/Xlsx/StylesLoader.php index 1e5892f..2cf77af 100644 --- a/src/Xlsx/StylesLoader.php +++ b/src/Xlsx/StylesLoader.php @@ -6,7 +6,7 @@ * Styles factory * * @author Antoine Guigan - * @copyright 2013 Akeneo SAS (http://www.akeneo.com) + * @copyright 2014 Akeneo SAS (http://www.akeneo.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ class StylesLoader diff --git a/src/Xlsx/ValueTransformer.php b/src/Xlsx/ValueTransformer.php index fdf1468..4c24685 100644 --- a/src/Xlsx/ValueTransformer.php +++ b/src/Xlsx/ValueTransformer.php @@ -6,7 +6,7 @@ * Transforms cell values according to their type * * @author Antoine Guigan - * @copyright 2013 Akeneo SAS (http://www.akeneo.com) + * @copyright 2014 Akeneo SAS (http://www.akeneo.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ class ValueTransformer diff --git a/src/Xlsx/ValueTransformerFactory.php b/src/Xlsx/ValueTransformerFactory.php index e3543bd..37ff4a6 100644 --- a/src/Xlsx/ValueTransformerFactory.php +++ b/src/Xlsx/ValueTransformerFactory.php @@ -6,7 +6,7 @@ * Creates ValueTransformer objects * * @author Antoine Guigan - * @copyright 2013 Akeneo SAS (http://www.akeneo.com) + * @copyright 2014 Akeneo SAS (http://www.akeneo.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ class ValueTransformerFactory diff --git a/src/Xlsx/WorksheetListReader.php b/src/Xlsx/WorksheetListReader.php index 9598e0c..0d5b699 100644 --- a/src/Xlsx/WorksheetListReader.php +++ b/src/Xlsx/WorksheetListReader.php @@ -6,7 +6,7 @@ * Reads the worksheet list from a workbook * * @author Antoine Guigan - * @copyright 2013 Akeneo SAS (http://www.akeneo.com) + * @copyright 2014 Akeneo SAS (http://www.akeneo.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ class WorksheetListReader diff --git a/src/Xlsx/XlsxParser.php b/src/Xlsx/XlsxParser.php index 8a6291f..7789868 100644 --- a/src/Xlsx/XlsxParser.php +++ b/src/Xlsx/XlsxParser.php @@ -6,7 +6,7 @@ * Entry point for XLSX reader * * @author Antoine Guigan - * @copyright 2013 Akeneo SAS (http://www.akeneo.com) + * @copyright 2014 Akeneo SAS (http://www.akeneo.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ class XlsxParser diff --git a/tests/CsvTest.php b/tests/CsvTest.php index 688a063..607ed2c 100644 --- a/tests/CsvTest.php +++ b/tests/CsvTest.php @@ -7,7 +7,7 @@ * Functional tests for CSV files * * @author Antoine Guigan - * @copyright 2013 Akeneo SAS (http://www.akeneo.com) + * @copyright 2014 Akeneo SAS (http://www.akeneo.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ class CsvTest extends PHPUnit_Framework_TestCase diff --git a/tests/XlsxTest.php b/tests/XlsxTest.php index c2f3b25..ec56dbf 100644 --- a/tests/XlsxTest.php +++ b/tests/XlsxTest.php @@ -7,7 +7,7 @@ * Functional tests for XLSX files * * @author Antoine Guigan - * @copyright 2013 Akeneo SAS (http://www.akeneo.com) + * @copyright 2014 Akeneo SAS (http://www.akeneo.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ class XlsxTest extends PHPUnit_Framework_TestCase From 107434d23ef2ebacf9744996451d7245512e970b Mon Sep 17 00:00:00 2001 From: Antoine Guigan Date: Mon, 9 Jun 2014 18:05:31 +0200 Subject: [PATCH 20/22] Code cleanup --- .../Csv/SpreadsheetLoaderSpec.php | 10 +++--- .../Xlsx/SpreadsheetLoaderSpec.php | 24 ++++++------- src/Csv/CsvParser.php | 8 ++--- src/Csv/Spreadsheet.php | 2 +- src/Csv/SpreadsheetLoader.php | 10 +++--- src/SpreadsheetInterface.php | 2 +- src/SpreadsheetLoader.php | 2 +- src/SpreadsheetLoaderInterface.php | 4 +-- src/SpreadsheetParser.php | 4 +-- src/Xlsx/RowIteratorFactory.php | 2 +- src/Xlsx/SharedStrings.php | 2 +- src/Xlsx/Spreadsheet.php | 4 +-- src/Xlsx/SpreadsheetLoader.php | 10 +++--- src/Xlsx/WorksheetListReader.php | 2 +- src/Xlsx/XlsxParser.php | 8 ++--- tests/CsvTest.php | 16 ++++----- tests/XlsxTest.php | 34 +++++++++---------- 17 files changed, 72 insertions(+), 72 deletions(-) diff --git a/spec/Akeneo/Component/SpreadsheetParser/Csv/SpreadsheetLoaderSpec.php b/spec/Akeneo/Component/SpreadsheetParser/Csv/SpreadsheetLoaderSpec.php index b155000..f5b32f2 100644 --- a/spec/Akeneo/Component/SpreadsheetParser/Csv/SpreadsheetLoaderSpec.php +++ b/spec/Akeneo/Component/SpreadsheetParser/Csv/SpreadsheetLoaderSpec.php @@ -22,13 +22,13 @@ public function it_is_initializable() $this->shouldHaveType('Akeneo\Component\SpreadsheetParser\Csv\SpreadsheetLoader'); } - public function it_creates_workbook_objects( + public function it_creates_spreadsheet_objects( RowIteratorFactory $rowIteratorFactory ) { - $workbook = $this->open('path'); - $workbook->getPath()->shouldReturn('path'); - $workbook->getSheetName()->shouldReturn('sheet'); - $workbook->getRowIteratorFactory()->shouldReturn($rowIteratorFactory); + $spreadsheet = $this->open('path'); + $spreadsheet->getPath()->shouldReturn('path'); + $spreadsheet->getSheetName()->shouldReturn('sheet'); + $spreadsheet->getRowIteratorFactory()->shouldReturn($rowIteratorFactory); } } diff --git a/spec/Akeneo/Component/SpreadsheetParser/Xlsx/SpreadsheetLoaderSpec.php b/spec/Akeneo/Component/SpreadsheetParser/Xlsx/SpreadsheetLoaderSpec.php index 79f75e1..9f7d84e 100644 --- a/spec/Akeneo/Component/SpreadsheetParser/Xlsx/SpreadsheetLoaderSpec.php +++ b/spec/Akeneo/Component/SpreadsheetParser/Xlsx/SpreadsheetLoaderSpec.php @@ -40,7 +40,7 @@ public function it_is_initializable() $this->shouldHaveType('Akeneo\Component\SpreadsheetParser\Xlsx\SpreadsheetLoader'); } - public function it_creates_workbook_objects( + public function it_creates_spreadsheet_objects( RelationshipsLoader $relationshipsLoader, SharedStringsLoader $sharedStringsLoader, StylesLoader $stylesLoader, @@ -52,24 +52,24 @@ public function it_creates_workbook_objects( ) { $archiveLoader->open('path')->willReturn($archive); - $workbook = $this->open('path'); - $workbook->getArchive()->shouldReturn($archive); - $workbook->getSharedStringsLoader()->shouldReturn($sharedStringsLoader); - $workbook->getStylesLoader()->shouldReturn($stylesLoader); - $workbook->getRowIteratorFactory()->shouldReturn($rowIteratorFactory); - $workbook->getWorksheetListReader()->shouldReturn($worksheetListReader); - $workbook->getValueTransformerFactory()->shouldReturn($valueTransformerFactory); - $workbook->getRelationshipsLoader()->shouldReturn($relationshipsLoader); + $spreadsheet = $this->open('path'); + $spreadsheet->getArchive()->shouldReturn($archive); + $spreadsheet->getSharedStringsLoader()->shouldReturn($sharedStringsLoader); + $spreadsheet->getStylesLoader()->shouldReturn($stylesLoader); + $spreadsheet->getRowIteratorFactory()->shouldReturn($rowIteratorFactory); + $spreadsheet->getWorksheetListReader()->shouldReturn($worksheetListReader); + $spreadsheet->getValueTransformerFactory()->shouldReturn($valueTransformerFactory); + $spreadsheet->getRelationshipsLoader()->shouldReturn($relationshipsLoader); } - public function it_caches_workbook_objects( + public function it_caches_spreadsheet_objects( ArchiveLoader $archiveLoader, Archive $archive ) { $archiveLoader->open('path')->shouldBeCalledTimes(1)->willReturn($archive); - $workbook = $this->open('path'); - $workbook->getArchive()->shouldReturn($archive); + $spreadsheet = $this->open('path'); + $spreadsheet->getArchive()->shouldReturn($archive); } } diff --git a/src/Csv/CsvParser.php b/src/Csv/CsvParser.php index a1060eb..adb4150 100644 --- a/src/Csv/CsvParser.php +++ b/src/Csv/CsvParser.php @@ -32,7 +32,7 @@ class CsvParser /** * @var SpreadsheetLoader */ - private static $workbookLoader; + private static $spreadsheetLoader; /** * Opens a CSV file @@ -51,15 +51,15 @@ public static function open($path) */ public static function getSpreadsheetLoader() { - if (!isset(self::$workbookLoader)) { - self::$workbookLoader = new SpreadsheetLoader( + if (!isset(self::$spreadsheetLoader)) { + self::$spreadsheetLoader = new SpreadsheetLoader( static::createRowIteratorFactory(), static::WORKBOOK_CLASS, static::SHEET_NAME ); } - return self::$workbookLoader; + return self::$spreadsheetLoader; } /** diff --git a/src/Csv/Spreadsheet.php b/src/Csv/Spreadsheet.php index 31a68ca..0671627 100644 --- a/src/Csv/Spreadsheet.php +++ b/src/Csv/Spreadsheet.php @@ -5,7 +5,7 @@ use Akeneo\Component\SpreadsheetParser\SpreadsheetInterface; /** - * Represents a CSV workbook + * Represents a CSV spreadsheet * * @author Antoine Guigan * @copyright 2014 Akeneo SAS (http://www.akeneo.com) diff --git a/src/Csv/SpreadsheetLoader.php b/src/Csv/SpreadsheetLoader.php index 2c9ac57..a073edd 100644 --- a/src/Csv/SpreadsheetLoader.php +++ b/src/Csv/SpreadsheetLoader.php @@ -21,7 +21,7 @@ class SpreadsheetLoader implements SpreadsheetLoaderInterface /** * @var string */ - protected $workbookClass; + protected $spreadsheetClass; /** * @@ -33,13 +33,13 @@ class SpreadsheetLoader implements SpreadsheetLoaderInterface * Constructor * * @param RowIteratorFactory $rowIteratorFactory - * @param string $workbookClass + * @param string $spreadsheetClass * @param string $sheetName */ - public function __construct(RowIteratorFactory $rowIteratorFactory, $workbookClass, $sheetName) + public function __construct(RowIteratorFactory $rowIteratorFactory, $spreadsheetClass, $sheetName) { $this->rowIteratorFactory = $rowIteratorFactory; - $this->workbookClass = $workbookClass; + $this->spreadsheetClass = $spreadsheetClass; $this->sheetName = $sheetName; } @@ -48,7 +48,7 @@ public function __construct(RowIteratorFactory $rowIteratorFactory, $workbookCla */ public function open($path) { - return new $this->workbookClass( + return new $this->spreadsheetClass( $this->rowIteratorFactory, $this->sheetName, $path diff --git a/src/SpreadsheetInterface.php b/src/SpreadsheetInterface.php index 76849e7..6a07cc9 100644 --- a/src/SpreadsheetInterface.php +++ b/src/SpreadsheetInterface.php @@ -3,7 +3,7 @@ namespace Akeneo\Component\SpreadsheetParser; /** - * Common interface for workbooks + * Common interface for spreadsheets * * @author Antoine Guigan * @copyright 2014 Akeneo SAS (http://www.akeneo.com) diff --git a/src/SpreadsheetLoader.php b/src/SpreadsheetLoader.php index 635c369..4511f7f 100644 --- a/src/SpreadsheetLoader.php +++ b/src/SpreadsheetLoader.php @@ -19,7 +19,7 @@ class SpreadsheetLoader implements SpreadsheetLoaderInterface protected $loaders = []; /** - * Opens a workbook + * Opens a spreadsheet * * @param string $path * @param string $type diff --git a/src/SpreadsheetLoaderInterface.php b/src/SpreadsheetLoaderInterface.php index 1a70c10..2993953 100644 --- a/src/SpreadsheetLoaderInterface.php +++ b/src/SpreadsheetLoaderInterface.php @@ -3,7 +3,7 @@ namespace Akeneo\Component\SpreadsheetParser; /** - * Common interface for workbook loaders + * Common interface for spreadsheet loaders * * @author Antoine Guigan * @copyright 2014 Akeneo SAS (http://www.akeneo.com) @@ -12,7 +12,7 @@ interface SpreadsheetLoaderInterface { /** - * Opens a workbook and returns a Spreadsheet object + * Opens a spreadsheet and returns a Spreadsheet object * * Spreadsheet objects are cached, and will be read only once * diff --git a/src/SpreadsheetParser.php b/src/SpreadsheetParser.php index 20e748f..d12fc3d 100644 --- a/src/SpreadsheetParser.php +++ b/src/SpreadsheetParser.php @@ -17,7 +17,7 @@ class SpreadsheetParser protected static $spreadsheetLoader; /** - * Opens a workbook + * Opens a spreadsheet * * @param string $path * @param string $type @@ -30,7 +30,7 @@ public static function open($path, $type = null) } /** - * Returns the workbook loader + * Returns the spreadsheet loader * * @return SpreadsheetLoaderInterface */ diff --git a/src/Xlsx/RowIteratorFactory.php b/src/Xlsx/RowIteratorFactory.php index 99c6aa7..b06aaf4 100644 --- a/src/Xlsx/RowIteratorFactory.php +++ b/src/Xlsx/RowIteratorFactory.php @@ -51,7 +51,7 @@ public function __construct( /** * Creates a row iterator for the XML given worksheet file * - * @param ValueTransformer $valueTransformer the value transformer for the workbook + * @param ValueTransformer $valueTransformer the value transformer for the spreadsheet * @param string $path the path to the extracted XML worksheet file * @param array $options options specific to the format * diff --git a/src/Xlsx/SharedStrings.php b/src/Xlsx/SharedStrings.php index ff2a978..efd9341 100644 --- a/src/Xlsx/SharedStrings.php +++ b/src/Xlsx/SharedStrings.php @@ -3,7 +3,7 @@ namespace Akeneo\Component\SpreadsheetParser\Xlsx; /** - * Contains the shared strings of an Excel workbook + * Contains the shared strings of an Excel spreadsheet * * @author Antoine Guigan * @copyright 2014 Akeneo SAS (http://www.akeneo.com) diff --git a/src/Xlsx/Spreadsheet.php b/src/Xlsx/Spreadsheet.php index b71b16a..5fc8a87 100644 --- a/src/Xlsx/Spreadsheet.php +++ b/src/Xlsx/Spreadsheet.php @@ -5,7 +5,7 @@ use Akeneo\Component\SpreadsheetParser\SpreadsheetInterface; /** - * Represents an XLSX workbook + * Represents an XLSX spreadsheet * * @author Antoine Guigan * @copyright 2014 Akeneo SAS (http://www.akeneo.com) @@ -20,7 +20,7 @@ class Spreadsheet implements SpreadsheetInterface const RELATIONSHIPS_PATH = 'xl/_rels/workbook.xml.rels'; /** - * @staticvar string Path to the workbooks file inside the XLSX archive + * @staticvar string Path to the spreadsheets file inside the XLSX archive */ const WORKBOOK_PATH = 'xl/workbook.xml'; diff --git a/src/Xlsx/SpreadsheetLoader.php b/src/Xlsx/SpreadsheetLoader.php index 69efed0..d32fef0 100644 --- a/src/Xlsx/SpreadsheetLoader.php +++ b/src/Xlsx/SpreadsheetLoader.php @@ -16,7 +16,7 @@ class SpreadsheetLoader implements SpreadsheetLoaderInterface /** * @var string */ - protected $workbookClass; + protected $spreadsheetClass; /** * @var RelationshipsLoader @@ -63,7 +63,7 @@ class SpreadsheetLoader implements SpreadsheetLoaderInterface * @param WorksheetListReader $worksheetListReader * @param ValueTransformerFactory $valueTransformerFactory * @param RowIteratorFactory $rowIteratorFactory - * @param string $workbookClass + * @param string $spreadsheetClass */ public function __construct( ArchiveLoader $archiveLoader, @@ -73,7 +73,7 @@ public function __construct( WorksheetListReader $worksheetListReader, ValueTransformerFactory $valueTransformerFactory, RowIteratorFactory $rowIteratorFactory, - $workbookClass + $spreadsheetClass ) { $this->relationshipsLoader = $relationshipsLoader; @@ -83,7 +83,7 @@ public function __construct( $this->valueTransformerFactory = $valueTransformerFactory; $this->rowIteratorFactory = $rowIteratorFactory; $this->archiveLoader = $archiveLoader; - $this->workbookClass = $workbookClass; + $this->spreadsheetClass = $spreadsheetClass; } /** @@ -93,7 +93,7 @@ public function open($path) { $archive = $this->archiveLoader->open($path); - return new $this->workbookClass( + return new $this->spreadsheetClass( $archive, $this->relationshipsLoader, $this->sharedStringsLoader, diff --git a/src/Xlsx/WorksheetListReader.php b/src/Xlsx/WorksheetListReader.php index 0d5b699..89c4e24 100644 --- a/src/Xlsx/WorksheetListReader.php +++ b/src/Xlsx/WorksheetListReader.php @@ -3,7 +3,7 @@ namespace Akeneo\Component\SpreadsheetParser\Xlsx; /** - * Reads the worksheet list from a workbook + * Reads the worksheet list from a spreadsheet * * @author Antoine Guigan * @copyright 2014 Akeneo SAS (http://www.akeneo.com) diff --git a/src/Xlsx/XlsxParser.php b/src/Xlsx/XlsxParser.php index 7789868..5fc5e14 100644 --- a/src/Xlsx/XlsxParser.php +++ b/src/Xlsx/XlsxParser.php @@ -59,7 +59,7 @@ class XlsxParser /** * @var SpreadsheetLoader */ - private static $workbookLoader; + private static $spreadsheetLoader; /** * Opens an XLSX file @@ -78,8 +78,8 @@ public static function open($path) */ public static function getSpreadsheetLoader() { - if (!isset(self::$workbookLoader)) { - self::$workbookLoader = new SpreadsheetLoader( + if (!isset(self::$spreadsheetLoader)) { + self::$spreadsheetLoader = new SpreadsheetLoader( static::createArchiveLoader(), static::createRelationshipsLoader(), static::createSharedStringsLoader(), @@ -91,7 +91,7 @@ public static function getSpreadsheetLoader() ); } - return self::$workbookLoader; + return self::$spreadsheetLoader; } /** diff --git a/tests/CsvTest.php b/tests/CsvTest.php index 607ed2c..8939c73 100644 --- a/tests/CsvTest.php +++ b/tests/CsvTest.php @@ -14,39 +14,39 @@ class CsvTest extends PHPUnit_Framework_TestCase { public function testReadFile() { - $workbook = SpreadsheetParser::open(__DIR__ . '/fixtures/test.csv'); - $this->assertEquals(['default'], $workbook->getWorksheets()); + $spreadsheet = SpreadsheetParser::open(__DIR__ . '/fixtures/test.csv'); + $this->assertEquals(['default'], $spreadsheet->getWorksheets()); $this->assertIteratesThrough( [ 0 => ['value', 'enclosed value', '15'], 1 => ['', 'value2', ''] ], - $workbook->createRowIterator(0) + $spreadsheet->createRowIterator(0) ); } public function testReadFileWithForcedFormat() { - $workbook = SpreadsheetParser::open(__DIR__ . '/fixtures/test.txt', CsvParser::FORMAT_NAME); - $this->assertEquals(['default'], $workbook->getWorksheets()); + $spreadsheet = SpreadsheetParser::open(__DIR__ . '/fixtures/test.txt', CsvParser::FORMAT_NAME); + $this->assertEquals(['default'], $spreadsheet->getWorksheets()); $this->assertIteratesThrough( [ 0 => ['value', 'enclosed value', '15'], 1 => ['', 'value2', ''] ], - $workbook->createRowIterator(0) + $spreadsheet->createRowIterator(0) ); } public function testCsvParserClass() { - $workbook = CsvParser::open(__DIR__ . '/fixtures/test.txt'); + $spreadsheet = CsvParser::open(__DIR__ . '/fixtures/test.txt'); $this->assertIteratesThrough( [ 0 => ['value', 'enclosed value', '15'], 1 => ['', 'value2', ''] ], - $workbook->createRowIterator(0) + $spreadsheet->createRowIterator(0) ); } diff --git a/tests/XlsxTest.php b/tests/XlsxTest.php index ec56dbf..de12e32 100644 --- a/tests/XlsxTest.php +++ b/tests/XlsxTest.php @@ -14,55 +14,55 @@ class XlsxTest extends PHPUnit_Framework_TestCase { public function testLibreOfficeFile() { - $workbook = SpreadsheetParser::open(__DIR__ . '/fixtures/libreoffice.xlsx'); - $this->assertEquals(['Sheet1', 'Sheet2'], $workbook->getWorksheets()); + $spreadsheet = SpreadsheetParser::open(__DIR__ . '/fixtures/libreoffice.xlsx'); + $this->assertEquals(['Sheet1', 'Sheet2'], $spreadsheet->getWorksheets()); $this->assertIteratesThrough( [ 2 => ['value1', '', 'value2'], 3 => ['value3', '2010-12-05 00:00', 154], 5 => ['test', '2006-08-12 15:46'] ], - $workbook->createRowIterator(0) + $spreadsheet->createRowIterator(0) ); $this->assertIteratesThrough( [ 4 => ['value7', '', 'value11'] ], - $workbook->createRowIterator(1) + $spreadsheet->createRowIterator(1) ); } public function testXlsParserClass() { - $workbook = XlsxParser::open(__DIR__ . '/fixtures/libreoffice.xlsx'); - $this->assertEquals(['Sheet1', 'Sheet2'], $workbook->getWorksheets()); + $spreadsheet = XlsxParser::open(__DIR__ . '/fixtures/libreoffice.xlsx'); + $this->assertEquals(['Sheet1', 'Sheet2'], $spreadsheet->getWorksheets()); $this->assertIteratesThrough( [ 2 => ['value1', '', 'value2'], 3 => ['value3', '2010-12-05 00:00', 154], 5 => ['test', '2006-08-12 15:46'] ], - $workbook->createRowIterator(0) + $spreadsheet->createRowIterator(0) ); $this->assertIteratesThrough( [ 4 => ['value7', '', 'value11'] ], - $workbook->createRowIterator(1) + $spreadsheet->createRowIterator(1) ); } public function testReadSameFileTwice() { - $workbook = SpreadsheetParser::open(__DIR__ . '/fixtures/libreoffice.xlsx'); - $this->assertEquals(['Sheet1', 'Sheet2'], $workbook->getWorksheets()); + $spreadsheet = SpreadsheetParser::open(__DIR__ . '/fixtures/libreoffice.xlsx'); + $this->assertEquals(['Sheet1', 'Sheet2'], $spreadsheet->getWorksheets()); $this->assertIteratesThrough( [ 2 => ['value1', '', 'value2'], 3 => ['value3', '2010-12-05 00:00', 154], 5 => ['test', '2006-08-12 15:46'] ], - $workbook->createRowIterator(0) + $spreadsheet->createRowIterator(0) ); $this->assertIteratesThrough( [ @@ -70,32 +70,32 @@ public function testReadSameFileTwice() 3 => ['value3', '2010-12-05 00:00', 154], 5 => ['test', '2006-08-12 15:46'] ], - $workbook->createRowIterator(0) + $spreadsheet->createRowIterator(0) ); } public function testMsOfficeFile() { - $workbook = SpreadsheetParser::open(__DIR__ . '/fixtures/msoffice.xlsx'); - $this->assertEquals(['Feuil1', 'Feuil2', 'Feuil3'], $workbook->getWorksheets()); + $spreadsheet = SpreadsheetParser::open(__DIR__ . '/fixtures/msoffice.xlsx'); + $this->assertEquals(['Feuil1', 'Feuil2', 'Feuil3'], $spreadsheet->getWorksheets()); $this->assertIteratesThrough( [ 3 => ['value1', '', '2014-12-15 00:00', '2015-01-15 12:16'], 5 => ['', 'value5'] ], - $workbook->createRowIterator(0) + $spreadsheet->createRowIterator(0) ); $this->assertIteratesThrough( [ 6 => ['', 'test1'], ], - $workbook->createRowIterator(1) + $spreadsheet->createRowIterator(1) ); $this->assertIteratesThrough( [ 1 => ['', '', '', 'test4'], ], - $workbook->createRowIterator(2) + $spreadsheet->createRowIterator(2) ); } From 5c14d8c31af78132f0f27a50d31bdee4f805ee73 Mon Sep 17 00:00:00 2001 From: Antoine Guigan Date: Mon, 9 Jun 2014 18:17:41 +0200 Subject: [PATCH 21/22] Added csv --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0a61e8d..e2cbeb7 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Akeneo Spreadsheet Parser This component is designed to extract data from spreadsheets, while being easy on resources, even for large files. -The actual version of the spreadsheet parser only works with xlsx files. +The actual version of the spreadsheet parser works with csv and xlsx files. [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/akeneo/spreadsheet-parser/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/akeneo/spreadsheet-parser/?branch=master) From 95fba111d8c6b9eeba7cb563dd6563ad34522204 Mon Sep 17 00:00:00 2001 From: Antoine Guigan Date: Mon, 9 Jun 2014 18:18:09 +0200 Subject: [PATCH 22/22] Changed branch alias for master --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 1fb946d..ce1ce51 100644 --- a/composer.json +++ b/composer.json @@ -30,7 +30,7 @@ }, "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.1.x-dev" } }, "config": {