diff --git a/README.md b/README.md index ea53ba2..44e5f08 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,7 @@ Archive7z\Info Object // $obj->setPassword('123'); +// $obj->getEntries('test', 100) foreach ($obj->getEntries() as $entry) { print_r($entry); /* diff --git a/src/Archive7z.php b/src/Archive7z.php index dc0addd..31d0a88 100644 --- a/src/Archive7z.php +++ b/src/Archive7z.php @@ -244,7 +244,7 @@ private function decorateCmdExtract(): array if (null !== $this->password) { $out[] = '-p'.$this->password; } else { - $out[] = '-p '; //todo + $out[] = '-p '; // todo } return $out; @@ -331,15 +331,9 @@ public function getContent(string $path): string */ public function getEntry(string $path): ?Entry { - $path = \str_replace('\\', '/', $path); + $entries = $this->getEntries($path, 1); - foreach ($this->getEntries() as $v) { - if ($v->getUnixPath() === $path) { - return $v; - } - } - - return null; + return $entries ? $entries[0] : null; } /** @@ -347,11 +341,13 @@ public function getEntry(string $path): ?Entry * * @return Entry[] */ - public function getEntries(): array + public function getEntries(?string $pathMask = null, ?int $limit = null): array { - $process = $this->makeProcess('l', \array_merge([ - '-slt', - ], $this->decorateCmdExtract())); + $process = $this->makeProcess('l', \array_merge( + ['-slt'], + $this->decorateCmdExtract(), + null !== $pathMask ? [$pathMask] : [], + )); $this->execute($process); @@ -359,7 +355,7 @@ public function getEntries(): array $list = []; $parser = new Parser($out); - foreach ($parser->parseEntries() as $v) { + foreach ($parser->parseEntries($limit) as $v) { $list[] = new Entry($this, $v); } @@ -373,7 +369,7 @@ public function getInfo(): Info { $process = $this->makeProcess('l', \array_merge([ '-slt', - ], $this->decorateCmdExtract())); + ], $this->decorateCmdExtract(), ['Archive7z fake path'])); $this->execute($process); diff --git a/src/Parser.php b/src/Parser.php index 70d1dad..3961166 100644 --- a/src/Parser.php +++ b/src/Parser.php @@ -69,7 +69,7 @@ public function parseHeader(): array /** * @return array> */ - public function parseEntries(): array + public function parseEntries(?int $limit = null): array { $isHead = true; $list = []; @@ -85,6 +85,9 @@ public function parseEntries(): array continue; } + if (null !== $limit && $i >= $limit) { + break; + } if ($value === $this->newFileListToken) { ++$i; continue; diff --git a/src/SolidMode.php b/src/SolidMode.php index 7169196..953068b 100644 --- a/src/SolidMode.php +++ b/src/SolidMode.php @@ -5,7 +5,7 @@ /** * @see https://documentation.help/7-Zip/method.htm#Solid */ -class SolidMode /* implements \Stringable*/ +class SolidMode /* implements \Stringable */ { public const ON = 'on'; public const OFF = 'off'; diff --git a/tests/Archive7zTest.php b/tests/Archive7zTest.php index 1e4a167..211a52b 100644 --- a/tests/Archive7zTest.php +++ b/tests/Archive7zTest.php @@ -349,8 +349,8 @@ public function entryProvider(): array ['totalcommander-9.21a/test.tar'], ['totalcommander-9.21a/test.zip'], ['winrar-5.61/test.zip'], - //['winrar-5.61/test4.rar'], // not supported - //['winrar-5.61/test5.rar'], // not supported + // ['winrar-5.61/test4.rar'], // not supported + // ['winrar-5.61/test5.rar'], // not supported ['linux/zip-0.3/test.zip'], ['linux/p7zip-16.02/test.7z'], ['linux/p7zip-16.02/test.tar'], @@ -485,8 +485,8 @@ public function testAddEntryLocalPathSubFiles(): void public function delProvider(): array { return [ - //['zip.7z'], // 7-Zip 21.02+ swears now at this - //['warnings.zip'], // not supported + // ['zip.7z'], // 7-Zip 21.02+ swears now at this + // ['warnings.zip'], // not supported ['7zip-18.05/test.7z'], ['7zip-18.05/test.tar'], ['7zip-18.05/test.wim'], @@ -494,8 +494,8 @@ public function delProvider(): array ['totalcommander-9.21a/test.tar'], ['totalcommander-9.21a/test.zip'], ['winrar-5.61/test.zip'], - //['winrar-5.61/test4.rar'], // not supported - //['winrar-5.61/test5.rar'], // not supported + // ['winrar-5.61/test4.rar'], // not supported + // ['winrar-5.61/test5.rar'], // not supported ['linux/zip-0.3/test.zip'], ['linux/p7zip-16.02/test.7z'], ['linux/p7zip-16.02/test.tar'], @@ -805,4 +805,61 @@ public function testInfo(string $archiveName): void self::assertIsString($info->getType()); self::assertGreaterThan(0, $info->getPhysicalSize()); } + + /** + * @dataProvider extractProvider + */ + public function testGetEntriesLimit(string $archiveName): void + { + $obj = new Archive7z($this->fixturesDir.'/'.$archiveName); + $entries = $obj->getEntries(null, 2); + + self::assertIsArray($entries); + self::assertCount(2, $entries); + self::assertInstanceOf(Entry::class, $entries[0]); + self::assertInstanceOf(Entry::class, $entries[1]); + } + + /** + * @dataProvider extractProvider + */ + public function testGetEntriesPathMask(string $archiveName): void + { + $path = 'test/test.txt'; + $obj = new Archive7z($this->fixturesDir.'/'.$archiveName); + $entries = $obj->getEntries($path); + + self::assertIsArray($entries); + self::assertCount(1, $entries); + self::assertInstanceOf(Entry::class, $entries[0]); + self::assertSame($path, $entries[0]->getUnixPath()); + } + + /** + * @dataProvider extractProvider + */ + public function testGetEntriesPathMaskCyrillic(string $archiveName): void + { + $path = 'чавес.jpg'; + $obj = new Archive7z($this->fixturesDir.'/'.$archiveName); + $entries = $obj->getEntries($path); + + self::assertIsArray($entries); + self::assertCount(1, $entries); + self::assertInstanceOf(Entry::class, $entries[0]); + self::assertSame($path, $entries[0]->getUnixPath()); + } + + /** + * @dataProvider extractProvider + */ + public function testGetEntriesPathMaskWildcard(string $archiveName): void + { + $path = 'test'; + $obj = new Archive7z($this->fixturesDir.'/'.$archiveName); + $entries = $obj->getEntries($path); + + self::assertIsArray($entries); + self::assertCount(3, $entries); // 1 folder + 2 files in the folder + } }