From 7e3eed2bb9f5880241c105553e86e24043f8c1a8 Mon Sep 17 00:00:00 2001 From: Giancarlos Salas Date: Fri, 24 Aug 2018 17:42:32 -0500 Subject: [PATCH 1/6] add compress interfaces --- src/Zip/CompressInterface.php | 24 ++++++++++++++++++++++++ src/Zip/DecompressInterface.php | 23 +++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 src/Zip/CompressInterface.php create mode 100644 src/Zip/DecompressInterface.php diff --git a/src/Zip/CompressInterface.php b/src/Zip/CompressInterface.php new file mode 100644 index 0000000..316a364 --- /dev/null +++ b/src/Zip/CompressInterface.php @@ -0,0 +1,24 @@ + Date: Fri, 24 Aug 2018 17:45:13 -0500 Subject: [PATCH 2/6] rename zipHelper to zipFly --- src/Ws/Services/BaseSunat.php | 6 +++--- src/Zip/{ZipHelper.php => ZipFly.php} | 4 ++-- tests/Ws/Zip/ZipFactoryTest.php | 16 ++++++++-------- 3 files changed, 13 insertions(+), 13 deletions(-) rename src/Zip/{ZipHelper.php => ZipFly.php} (99%) diff --git a/src/Ws/Services/BaseSunat.php b/src/Ws/Services/BaseSunat.php index acdba28..c344be6 100644 --- a/src/Ws/Services/BaseSunat.php +++ b/src/Ws/Services/BaseSunat.php @@ -12,7 +12,7 @@ use Greenter\Validator\ErrorCodeProviderInterface; use Greenter\Ws\Reader\CdrReaderInterface; use Greenter\Ws\Reader\DomCdrReader; -use Greenter\Zip\ZipHelper; +use Greenter\Zip\ZipFly; /** * Class BaseSunat. @@ -20,7 +20,7 @@ class BaseSunat { /** - * @var ZipHelper + * @var ZipFly */ private $zipper; @@ -52,7 +52,7 @@ public function setCodeProvider(ErrorCodeProviderInterface $codeProvider) */ public function __construct() { - $this->zipper = new ZipHelper(); + $this->zipper = new ZipFly(); $this->cdrReader = new DomCdrReader(); } diff --git a/src/Zip/ZipHelper.php b/src/Zip/ZipFly.php similarity index 99% rename from src/Zip/ZipHelper.php rename to src/Zip/ZipFly.php index cad3302..aaaf7c2 100644 --- a/src/Zip/ZipHelper.php +++ b/src/Zip/ZipFly.php @@ -11,7 +11,7 @@ /** * Class ZipFile. */ -class ZipHelper +class ZipFly { const UNZIP_FORMAT = 'Vsig/vver/vflag/vmeth/vmodt/vmodd/Vcrc/Vcsize/Vsize/vnamelen/vexlen'; @@ -41,7 +41,7 @@ class ZipHelper private $old_offset; /** - * ZipHelper constructor. + * ZipFly constructor. */ public function __construct() { diff --git a/tests/Ws/Zip/ZipFactoryTest.php b/tests/Ws/Zip/ZipFactoryTest.php index 0942a6e..6d16d59 100644 --- a/tests/Ws/Zip/ZipFactoryTest.php +++ b/tests/Ws/Zip/ZipFactoryTest.php @@ -8,7 +8,7 @@ namespace Tests\Greenter\Zip; -use Greenter\Zip\ZipHelper; +use Greenter\Zip\ZipFly; /** * Class ZipFactoryTest @@ -28,7 +28,7 @@ public function testCompressFile() public function testMultipleCompress() { $txtContent = '

GREENTER WS

'; - $helper = new ZipHelper(); + $helper = new ZipFly(); $zip = $helper->compress('myFile.xml', self::DATA_XML); $zip2 = $helper->compress('myFile.xml', $txtContent); @@ -42,7 +42,7 @@ public function testMultipleCompress() public function testDecompressLastFile() { $zipContent = $this->createZip(); - $helper = new ZipHelper(); + $helper = new ZipFly(); $content = $helper->decompressXmlFile($zipContent); $this->assertEquals(self::DATA_XML, $content); @@ -50,7 +50,7 @@ public function testDecompressLastFile() public function testUnixTime() { - $zip = new ZipHelper(); + $zip = new ZipFly(); $result = $zip->unix2DosTime(181233012); $this->assertEquals(2162688, $result); @@ -58,7 +58,7 @@ public function testUnixTime() public function testInvalidZip() { - $zip = new ZipHelper(); + $zip = new ZipFly(); $res = $zip->decompressXmlFile(''); $this->assertEmpty($res); @@ -66,17 +66,17 @@ public function testInvalidZip() public function testNotXmlZip() { - $helper = new ZipHelper(); + $helper = new ZipFly(); $zip = $helper->compress('myFile.txt', 'TEST TEXT 1'); - $res = (new ZipHelper())->decompressXmlFile($zip); + $res = (new ZipFly())->decompressXmlFile($zip); $this->assertEmpty($res); } private function createZip() { - $helper = new ZipHelper(); + $helper = new ZipFly(); $zip = $helper->compress('myFile.xml', self::DATA_XML); return $zip; From 399a9b25eb0bea1d007369cc317daa3d6bc52d4c Mon Sep 17 00:00:00 2001 From: Giancarlos Salas Date: Fri, 24 Aug 2018 18:18:15 -0500 Subject: [PATCH 3/6] zipFly implements compress methods --- src/Ws/Services/BaseSunat.php | 22 ++++++++++++- src/Zip/DecompressInterface.php | 5 +-- src/Zip/ZipFly.php | 55 ++++++++++++++------------------- tests/Ws/Zip/ZipFactoryTest.php | 30 +++++++++++++++--- 4 files changed, 73 insertions(+), 39 deletions(-) diff --git a/src/Ws/Services/BaseSunat.php b/src/Ws/Services/BaseSunat.php index c344be6..aeeb863 100644 --- a/src/Ws/Services/BaseSunat.php +++ b/src/Ws/Services/BaseSunat.php @@ -124,7 +124,7 @@ protected function compress($filename, $xml) */ protected function extractResponse($zipContent) { - $xml = $this->zipper->decompressXmlFile($zipContent); + $xml = $this->getXmlResponse($zipContent); return $this->cdrReader->getCdrResponse($xml); } @@ -142,4 +142,24 @@ protected function getMessageError($code) return $this->codeProvider->getValue($code); } + + private function getXmlResponse($content) + { + $filter = function ($filename) { + return strtolower($this->getFileExtension($filename)) === 'xml'; + }; + $files = $this->zipper->decompress($content, $filter); + + return count($files) === 0 ? '' : $files[0]['content']; + } + + private function getFileExtension($filename) + { + $lastDotPos = strrpos($filename, '.'); + if (!$lastDotPos) { + return ''; + } + + return substr($filename, $lastDotPos + 1); + } } diff --git a/src/Zip/DecompressInterface.php b/src/Zip/DecompressInterface.php index 4a7fa7f..aeaa383 100644 --- a/src/Zip/DecompressInterface.php +++ b/src/Zip/DecompressInterface.php @@ -16,8 +16,9 @@ interface DecompressInterface /** * Extract files. * - * @param string $content + * @param string $content + * @param callable|null $filter * @return array */ - public function decompress($content); + public function decompress($content, callable $filter = null); } \ No newline at end of file diff --git a/src/Zip/ZipFly.php b/src/Zip/ZipFly.php index aaaf7c2..ff17a10 100644 --- a/src/Zip/ZipFly.php +++ b/src/Zip/ZipFly.php @@ -11,7 +11,7 @@ /** * Class ZipFile. */ -class ZipFly +class ZipFly implements CompressInterface, DecompressInterface { const UNZIP_FORMAT = 'Vsig/vver/vflag/vmeth/vmodt/vmodd/Vcrc/Vcsize/Vsize/vnamelen/vexlen'; @@ -175,55 +175,48 @@ public function compress($filename, $content) return $zip; } + private function clear() + { + $this->datasec = []; + $this->ctrl_dir = []; + $this->old_offset = 0; + } + /** - * Retorna el contenido del primer xml dentro del zip. - * - * @param string $zipContent + * Extract files. * - * @return string + * @param string $content + * @param callable|null $filter + * @return array */ - public function decompressXmlFile($zipContent) + public function decompress($content, callable $filter = null) { $start = 0; - $max = 10; - while ($max > 0) { - $dat = substr($zipContent, $start, 30); + $result = []; + + while (true) { + $dat = substr($content, $start, 30); if (empty($dat)) { break; } $head = unpack(self::UNZIP_FORMAT, $dat); - $filename = substr(substr($zipContent, $start), 30, $head['namelen']); + $filename = substr(substr($content, $start), 30, $head['namelen']); if (empty($filename)) { break; } $count = 30 + $head['namelen'] + $head['exlen']; - if (strtolower($this->getFileExtension($filename)) == 'xml') { - return gzinflate(substr($zipContent, $start + $count, $head['csize'])); + if (!$filter || $filter($filename)) { + $result[] = [ + 'filename' => $filename, + 'content' => gzinflate(substr($content, $start + $count, $head['csize'])) + ]; } $start += $count + $head['csize']; - --$max; } - return ''; - } - - private function getFileExtension($filename) - { - $lastDotPos = strrpos($filename, '.'); - if (!$lastDotPos) { - return ''; - } - - return substr($filename, $lastDotPos + 1); - } - - private function clear() - { - $this->datasec = []; - $this->ctrl_dir = []; - $this->old_offset = 0; + return $result; } } diff --git a/tests/Ws/Zip/ZipFactoryTest.php b/tests/Ws/Zip/ZipFactoryTest.php index 6d16d59..eba7437 100644 --- a/tests/Ws/Zip/ZipFactoryTest.php +++ b/tests/Ws/Zip/ZipFactoryTest.php @@ -32,8 +32,8 @@ public function testMultipleCompress() $zip = $helper->compress('myFile.xml', self::DATA_XML); $zip2 = $helper->compress('myFile.xml', $txtContent); - $result1 = $helper->decompressXmlFile($zip); - $result2 = $helper->decompressXmlFile($zip2); + $result1 = $this->getXmlResponse($helper, $zip); + $result2 = $this->getXmlResponse($helper, $zip2); $this->assertEquals(self::DATA_XML, $result1); $this->assertEquals($txtContent, $result2); @@ -43,7 +43,7 @@ public function testDecompressLastFile() { $zipContent = $this->createZip(); $helper = new ZipFly(); - $content = $helper->decompressXmlFile($zipContent); + $content = $this->getXmlResponse($helper, $zipContent); $this->assertEquals(self::DATA_XML, $content); } @@ -59,7 +59,7 @@ public function testUnixTime() public function testInvalidZip() { $zip = new ZipFly(); - $res = $zip->decompressXmlFile(''); + $res = $zip->decompress(''); $this->assertEmpty($res); } @@ -69,7 +69,7 @@ public function testNotXmlZip() $helper = new ZipFly(); $zip = $helper->compress('myFile.txt', 'TEST TEXT 1'); - $res = (new ZipFly())->decompressXmlFile($zip); + $res = $this->getXmlResponse(new ZipFly(), $zip); $this->assertEmpty($res); } @@ -81,4 +81,24 @@ private function createZip() return $zip; } + + private function getXmlResponse(ZipFly $zipper, $content) + { + $filter = function ($filename) { + return strtolower($this->getFileExtension($filename)) === 'xml'; + }; + $files = $zipper->decompress($content, $filter); + + return count($files) === 0 ? '' : $files[0]['content']; + } + + private function getFileExtension($filename) + { + $lastDotPos = strrpos($filename, '.'); + if (!$lastDotPos) { + return ''; + } + + return substr($filename, $lastDotPos + 1); + } } From 818efbb00f02f8bab3cf3394ac05ec0088316a57 Mon Sep 17 00:00:00 2001 From: Giancarlos Salas Date: Wed, 29 Aug 2018 17:54:26 -0500 Subject: [PATCH 4/6] add ZipArchive decompress --- src/Zip/ZipFileDecompress.php | 56 +++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 src/Zip/ZipFileDecompress.php diff --git a/src/Zip/ZipFileDecompress.php b/src/Zip/ZipFileDecompress.php new file mode 100644 index 0000000..735dbe8 --- /dev/null +++ b/src/Zip/ZipFileDecompress.php @@ -0,0 +1,56 @@ +open($temp) === true && $zip->numFiles > 0) { + $output = iterator_to_array($this->getFiles($zip, $filter)); + } + $zip->close(); + unlink($temp); + + return $output; + } + + private function getFiles(\ZipArchive $zip, $filter) + { + $total = $zip->numFiles; + for ($i = 0; $i < $total; $i++) { + $name = $zip->getNameIndex($i); + if (false === $name) { + continue; + } + + if (!$filter || $filter($name)) { + yield [ + 'filename' => $name, + 'content' => $zip->getFromIndex($i) + ]; + } + } + } +} \ No newline at end of file From 147340cdf5ab1c3b0d05d99d7d2daf875ef02879 Mon Sep 17 00:00:00 2001 From: Giancarlos Salas Date: Wed, 29 Aug 2018 17:55:17 -0500 Subject: [PATCH 5/6] add test ZipArchive decompress --- tests/Ws/Zip/ZipFileDecompressTest.php | 71 ++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 tests/Ws/Zip/ZipFileDecompressTest.php diff --git a/tests/Ws/Zip/ZipFileDecompressTest.php b/tests/Ws/Zip/ZipFileDecompressTest.php new file mode 100644 index 0000000..5780d6d --- /dev/null +++ b/tests/Ws/Zip/ZipFileDecompressTest.php @@ -0,0 +1,71 @@ +zip = new ZipFileDecompress(); + } + + public function testDecompressEmptyFile() + { + $items = $this->zip->decompress(''); + + $this->assertEquals(0, count($items)); + } + + public function testDecompressWithoutFilter() + { + $content = $this->createZipWithPlainFile('my.txt'); + $items = $this->zip->decompress($content); + + $this->assertEquals(1, count($items)); + } + + public function testDecompressWithFilterNotFound() + { + $content = $this->createZipWithPlainFile('my.txt'); + $items = $this->zip->decompress($content, function ($filename) { + return strpos($filename, 'xml'); + }); + + $this->assertEquals(0, count($items)); + } + + public function testDecompressWithFilterFound() + { + $content = $this->createZipWithPlainFile('my.xml'); + $items = $this->zip->decompress($content, function ($filename) { + return strpos($filename, 'xml'); + }); + + $this->assertEquals(1, count($items)); + } + + private function createZipWithPlainFile($name) + { + $helper = new ZipFly(); + $zip = $helper->compress($name, '--'); + + return $zip; + } +} \ No newline at end of file From fa51d998d20bb68e3edd911a492bf0ae3d90e894 Mon Sep 17 00:00:00 2001 From: Giancarlos Salas Date: Wed, 29 Aug 2018 18:06:29 -0500 Subject: [PATCH 6/6] use ZipFileDecompress --- src/Ws/Services/BaseSunat.php | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/Ws/Services/BaseSunat.php b/src/Ws/Services/BaseSunat.php index aeeb863..2cc98bb 100644 --- a/src/Ws/Services/BaseSunat.php +++ b/src/Ws/Services/BaseSunat.php @@ -12,6 +12,9 @@ use Greenter\Validator\ErrorCodeProviderInterface; use Greenter\Ws\Reader\CdrReaderInterface; use Greenter\Ws\Reader\DomCdrReader; +use Greenter\Zip\CompressInterface; +use Greenter\Zip\DecompressInterface; +use Greenter\Zip\ZipFileDecompress; use Greenter\Zip\ZipFly; /** @@ -20,9 +23,14 @@ class BaseSunat { /** - * @var ZipFly + * @var CompressInterface */ - private $zipper; + private $compressor; + + /** + * @var DecompressInterface + */ + private $decompressor; /** * @var CdrReaderInterface @@ -52,7 +60,9 @@ public function setCodeProvider(ErrorCodeProviderInterface $codeProvider) */ public function __construct() { - $this->zipper = new ZipFly(); + //TODO: Inject + $this->compressor = new ZipFly(); + $this->decompressor = new ZipFileDecompress(); $this->cdrReader = new DomCdrReader(); } @@ -114,7 +124,7 @@ protected function getErrorFromFault(\SoapFault $fault) */ protected function compress($filename, $xml) { - return $this->zipper->compress($filename, $xml); + return $this->compressor->compress($filename, $xml); } /** @@ -148,7 +158,7 @@ private function getXmlResponse($content) $filter = function ($filename) { return strtolower($this->getFileExtension($filename)) === 'xml'; }; - $files = $this->zipper->decompress($content, $filter); + $files = $this->decompressor->decompress($content, $filter); return count($files) === 0 ? '' : $files[0]['content']; }