ZipFileTest.php 66 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007
  1. <?php
  2. namespace PhpZip;
  3. use PhpZip\Model\ZipEntry;
  4. use PhpZip\Model\ZipInfo;
  5. use PhpZip\Util\CryptoUtil;
  6. use PhpZip\Util\FilesUtil;
  7. use Psr\Http\Message\ResponseInterface;
  8. /**
  9. * ZipFile test
  10. */
  11. class ZipFileTest extends ZipTestCase
  12. {
  13. /**
  14. * @expectedException \PhpZip\Exception\InvalidArgumentException
  15. * @expectedExceptionMessage can't exists
  16. */
  17. public function testOpenFileCantExists()
  18. {
  19. $zipFile = new ZipFile();
  20. $zipFile->openFile(uniqid());
  21. }
  22. /**
  23. * @expectedException \PhpZip\Exception\ZipException
  24. * @expectedExceptionMessage can't open
  25. */
  26. public function testOpenFileCantOpen()
  27. {
  28. if (0 === posix_getuid()) {
  29. $this->markTestSkipped('Skip the test for a user with root privileges');
  30. }
  31. self::assertNotFalse(file_put_contents($this->outputFilename, 'content'));
  32. self::assertTrue(chmod($this->outputFilename, 0222));
  33. $zipFile = new ZipFile();
  34. $zipFile->openFile($this->outputFilename);
  35. }
  36. /**
  37. * @expectedException \PhpZip\Exception\ZipException
  38. * @expectedExceptionMessage Invalid zip file
  39. */
  40. public function testOpenFileEmptyFile()
  41. {
  42. self::assertNotFalse(touch($this->outputFilename));
  43. $zipFile = new ZipFile();
  44. $zipFile->openFile($this->outputFilename);
  45. }
  46. /**
  47. * @expectedException \PhpZip\Exception\ZipException
  48. * @expectedExceptionMessage Expected Local File Header or (ZIP64) End Of Central Directory Record
  49. */
  50. public function testOpenFileInvalidZip()
  51. {
  52. self::assertNotFalse(file_put_contents($this->outputFilename, CryptoUtil::randomBytes(255)));
  53. $zipFile = new ZipFile();
  54. $zipFile->openFile($this->outputFilename);
  55. }
  56. /**
  57. * @expectedException \PhpZip\Exception\InvalidArgumentException
  58. * @expectedExceptionMessage Data not available
  59. */
  60. public function testOpenFromStringNullString()
  61. {
  62. $zipFile = new ZipFile();
  63. $zipFile->openFromString(null);
  64. }
  65. /**
  66. * @expectedException \PhpZip\Exception\InvalidArgumentException
  67. * @expectedExceptionMessage Data not available
  68. */
  69. public function testOpenFromStringEmptyString()
  70. {
  71. $zipFile = new ZipFile();
  72. $zipFile->openFromString("");
  73. }
  74. /**
  75. * @expectedException \PhpZip\Exception\ZipException
  76. * @expectedExceptionMessage Expected Local File Header or (ZIP64) End Of Central Directory Record
  77. */
  78. public function testOpenFromStringInvalidZip()
  79. {
  80. $zipFile = new ZipFile();
  81. $zipFile->openFromString(CryptoUtil::randomBytes(255));
  82. }
  83. public function testOpenFromString()
  84. {
  85. $zipFile = new ZipFile();
  86. $zipFile->addFromString('file', 'content');
  87. $zipFile['file2'] = 'content 2';
  88. $zipContents = $zipFile->outputAsString();
  89. $zipFile->close();
  90. $zipFile->openFromString($zipContents);
  91. self::assertEquals($zipFile->count(), 2);
  92. self::assertTrue(isset($zipFile['file']));
  93. self::assertTrue(isset($zipFile['file2']));
  94. self::assertEquals($zipFile['file'], 'content');
  95. self::assertEquals($zipFile['file2'], 'content 2');
  96. $zipFile->close();
  97. }
  98. /**
  99. * @expectedException \PhpZip\Exception\InvalidArgumentException
  100. * @expectedExceptionMessage Invalid stream resource
  101. */
  102. public function testOpenFromStreamNullStream()
  103. {
  104. $zipFile = new ZipFile();
  105. $zipFile->openFromStream(null);
  106. }
  107. /**
  108. * @expectedException \PhpZip\Exception\InvalidArgumentException
  109. * @expectedExceptionMessage Invalid stream resource
  110. */
  111. public function testOpenFromStreamInvalidResourceType()
  112. {
  113. $zipFile = new ZipFile();
  114. /** @noinspection PhpParamsInspection */
  115. $zipFile->openFromStream("stream resource");
  116. }
  117. /**
  118. * @expectedException \PhpZip\Exception\InvalidArgumentException
  119. * @expectedExceptionMessage Invalid resource type - gd.
  120. */
  121. public function testOpenFromStreamInvalidResourceType2()
  122. {
  123. $zipFile = new ZipFile();
  124. if (!extension_loaded("gd")) {
  125. $this->markTestSkipped('not extension gd');
  126. }
  127. $zipFile->openFromStream(imagecreate(1, 1));
  128. }
  129. /**
  130. * @expectedException \PhpZip\Exception\InvalidArgumentException
  131. * @expectedExceptionMessage Invalid stream type - dir.
  132. */
  133. public function testOpenFromStreamInvalidResourceType3()
  134. {
  135. $zipFile = new ZipFile();
  136. $zipFile->openFromStream(opendir(__DIR__));
  137. }
  138. /**
  139. * @expectedException \PhpZip\Exception\InvalidArgumentException
  140. * @expectedExceptionMessage Resource cannot seekable stream.
  141. */
  142. public function testOpenFromStreamNoSeekable()
  143. {
  144. if (!$fp = @fopen("http://localhost", 'r')) {
  145. if (!$fp = @fopen("http://example.org", 'r')) {
  146. $this->markTestSkipped('not connected to localhost or remote host');
  147. return;
  148. }
  149. }
  150. $zipFile = new ZipFile();
  151. $zipFile->openFromStream($fp);
  152. }
  153. /**
  154. * @expectedException \PhpZip\Exception\ZipException
  155. * @expectedExceptionMessage Invalid zip file
  156. */
  157. public function testOpenFromStreamEmptyContents()
  158. {
  159. $fp = fopen($this->outputFilename, 'w+b');
  160. $zipFile = new ZipFile();
  161. $zipFile->openFromStream($fp);
  162. }
  163. /**
  164. * @expectedException \PhpZip\Exception\ZipException
  165. * @expectedExceptionMessage Expected Local File Header or (ZIP64) End Of Central Directory Record
  166. */
  167. public function testOpenFromStreamInvalidZip()
  168. {
  169. $fp = fopen($this->outputFilename, 'w+b');
  170. fwrite($fp, CryptoUtil::randomBytes(255));
  171. $zipFile = new ZipFile();
  172. $zipFile->openFromStream($fp);
  173. }
  174. public function testOpenFromStream()
  175. {
  176. $zipFile = new ZipFile();
  177. $zipFile
  178. ->addFromString('file', 'content')
  179. ->saveAsFile($this->outputFilename)
  180. ->close();
  181. $handle = fopen($this->outputFilename, 'rb');
  182. $zipFile->openFromStream($handle);
  183. self::assertEquals($zipFile->count(), 1);
  184. self::assertTrue(isset($zipFile['file']));
  185. self::assertEquals($zipFile['file'], 'content');
  186. $zipFile->close();
  187. }
  188. /**
  189. * Test create, open and extract empty archive.
  190. */
  191. public function testEmptyArchive()
  192. {
  193. $zipFile = new ZipFile();
  194. $zipFile
  195. ->saveAsFile($this->outputFilename)
  196. ->close();
  197. self::assertCorrectEmptyZip($this->outputFilename);
  198. self::assertTrue(mkdir($this->outputDirname, 0755, true));
  199. $zipFile->openFile($this->outputFilename);
  200. self::assertEquals($zipFile->count(), 0);
  201. $zipFile
  202. ->extractTo($this->outputDirname)
  203. ->close();
  204. self::assertTrue(FilesUtil::isEmptyDir($this->outputDirname));
  205. }
  206. /**
  207. * No modified archive
  208. *
  209. * @see ZipOutputFile::create()
  210. */
  211. public function testNoModifiedArchive()
  212. {
  213. self::assertTrue(mkdir($this->outputDirname, 0755, true));
  214. $fileActual = $this->outputDirname . DIRECTORY_SEPARATOR . 'file_actual.zip';
  215. $fileExpected = $this->outputDirname . DIRECTORY_SEPARATOR . 'file_expected.zip';
  216. $zipFile = new ZipFile();
  217. $zipFile->addDirRecursive(__DIR__.'/../../src');
  218. $sourceCount = $zipFile->count();
  219. self::assertTrue($sourceCount > 0);
  220. $zipFile
  221. ->saveAsFile($fileActual)
  222. ->close();
  223. self::assertCorrectZipArchive($fileActual);
  224. $zipFile
  225. ->openFile($fileActual)
  226. ->saveAsFile($fileExpected);
  227. self::assertCorrectZipArchive($fileExpected);
  228. $zipFileExpected = new ZipFile();
  229. $zipFileExpected->openFile($fileExpected);
  230. self::assertEquals($zipFile->count(), $sourceCount);
  231. self::assertEquals($zipFileExpected->count(), $zipFile->count());
  232. self::assertEquals($zipFileExpected->getListFiles(), $zipFile->getListFiles());
  233. foreach ($zipFile as $entryName => $content) {
  234. self::assertEquals($zipFileExpected[$entryName], $content);
  235. }
  236. $zipFileExpected->close();
  237. $zipFile->close();
  238. }
  239. /**
  240. * Create archive and add files.
  241. *
  242. * @see ZipOutputFile::addFromString()
  243. * @see ZipOutputFile::addFromFile()
  244. * @see ZipOutputFile::addFromStream()
  245. * @see ZipFile::getEntryContents()
  246. */
  247. public function testCreateArchiveAndAddFiles()
  248. {
  249. $outputFromString = file_get_contents(__FILE__);
  250. $outputFromString2 = file_get_contents(dirname(dirname(__DIR__)) . DIRECTORY_SEPARATOR . 'README.md');
  251. $outputFromFile = file_get_contents(dirname(dirname(__DIR__)) . DIRECTORY_SEPARATOR . 'phpunit.xml');
  252. $outputFromStream = file_get_contents(dirname(dirname(__DIR__)) . DIRECTORY_SEPARATOR . 'composer.json');
  253. $filenameFromString = basename(__FILE__);
  254. $filenameFromString2 = 'test_file.txt';
  255. $filenameFromFile = 'data/test file.txt';
  256. $filenameFromStream = 'data/ডিরেক্টরি/αρχείο.json';
  257. $emptyDirName = 'empty dir/пустой каталог/空目錄/ไดเรกทอรีที่ว่างเปล่า/';
  258. $emptyDirName2 = 'empty dir/пустой каталог/';
  259. $emptyDirName3 = 'empty dir/пустой каталог/ещё один пустой каталог/';
  260. $tempFile = tempnam(sys_get_temp_dir(), 'txt');
  261. file_put_contents($tempFile, $outputFromFile);
  262. $tempStream = tmpfile();
  263. fwrite($tempStream, $outputFromStream);
  264. $zipFile = new ZipFile;
  265. $zipFile
  266. ->addFromString($filenameFromString, $outputFromString)
  267. ->addFile($tempFile, $filenameFromFile)
  268. ->addFromStream($tempStream, $filenameFromStream)
  269. ->addEmptyDir($emptyDirName);
  270. $zipFile[$filenameFromString2] = $outputFromString2;
  271. $zipFile[$emptyDirName2] = null;
  272. $zipFile[$emptyDirName3] = 'this content ignoring';
  273. self::assertEquals(count($zipFile), 7);
  274. $zipFile
  275. ->saveAsFile($this->outputFilename)
  276. ->close();
  277. unlink($tempFile);
  278. self::assertCorrectZipArchive($this->outputFilename);
  279. $zipFile->openFile($this->outputFilename);
  280. self::assertEquals(count($zipFile), 7);
  281. self::assertEquals($zipFile[$filenameFromString], $outputFromString);
  282. self::assertEquals($zipFile[$filenameFromFile], $outputFromFile);
  283. self::assertEquals($zipFile[$filenameFromStream], $outputFromStream);
  284. self::assertEquals($zipFile[$filenameFromString2], $outputFromString2);
  285. self::assertTrue(isset($zipFile[$emptyDirName]));
  286. self::assertTrue(isset($zipFile[$emptyDirName2]));
  287. self::assertTrue(isset($zipFile[$emptyDirName3]));
  288. self::assertTrue($zipFile->isDirectory($emptyDirName));
  289. self::assertTrue($zipFile->isDirectory($emptyDirName2));
  290. self::assertTrue($zipFile->isDirectory($emptyDirName3));
  291. $listFiles = $zipFile->getListFiles();
  292. self::assertEquals($listFiles[0], $filenameFromString);
  293. self::assertEquals($listFiles[1], $filenameFromFile);
  294. self::assertEquals($listFiles[2], $filenameFromStream);
  295. self::assertEquals($listFiles[3], $emptyDirName);
  296. self::assertEquals($listFiles[4], $filenameFromString2);
  297. self::assertEquals($listFiles[5], $emptyDirName2);
  298. self::assertEquals($listFiles[6], $emptyDirName3);
  299. $zipFile->close();
  300. }
  301. public function testEmptyContent()
  302. {
  303. $zipFile = new ZipFile();
  304. $zipFile['file'] = '';
  305. $zipFile->saveAsFile($this->outputFilename);
  306. $zipFile->close();
  307. $zipFile->openFile($this->outputFilename);
  308. self::assertEquals($zipFile['file'], '');
  309. $zipFile->close();
  310. }
  311. /**
  312. * Test compression method from image file.
  313. */
  314. public function testCompressionMethodFromImageMimeType()
  315. {
  316. if (!function_exists('mime_content_type')) {
  317. $this->markTestSkipped('Function mime_content_type not exists');
  318. }
  319. $outputFilename = $this->outputFilename;
  320. $this->outputFilename .= '.gif';
  321. self::assertNotFalse(
  322. file_put_contents(
  323. $this->outputFilename,
  324. base64_decode('R0lGODlhAQABAJAAAP8AAAAAACH5BAUQAAAALAAAAAABAAEAAAICBAEAOw==')
  325. )
  326. );
  327. $basename = basename($this->outputFilename);
  328. $zipFile = new ZipFile();
  329. $zipFile->addFile($this->outputFilename, $basename);
  330. $zipFile->saveAsFile($outputFilename);
  331. unlink($this->outputFilename);
  332. $this->outputFilename = $outputFilename;
  333. $zipFile->openFile($this->outputFilename);
  334. $info = $zipFile->getEntryInfo($basename);
  335. self::assertEquals($info->getMethodName(), 'No compression');
  336. $zipFile->close();
  337. }
  338. /**
  339. * Rename zip entry name.
  340. */
  341. public function testRename()
  342. {
  343. $oldName = basename(__FILE__);
  344. $newName = 'tests/' . $oldName;
  345. $zipFile = new ZipFile();
  346. $zipFile->addDir(__DIR__);
  347. $zipFile->saveAsFile($this->outputFilename);
  348. $zipFile->close();
  349. self::assertCorrectZipArchive($this->outputFilename);
  350. $zipFile->openFile($this->outputFilename);
  351. $zipFile->rename($oldName, $newName);
  352. $zipFile->addFromString('file1.txt', 'content');
  353. $zipFile->addFromString('file2.txt', 'content');
  354. $zipFile->addFromString('file3.txt', 'content');
  355. $zipFile->rename('file1.txt', 'file_long_name.txt');
  356. $zipFile->rename('file2.txt', 'file4.txt');
  357. $zipFile->rename('file3.txt', 'fi.txt');
  358. $zipFile->saveAsFile($this->outputFilename);
  359. $zipFile->close();
  360. self::assertCorrectZipArchive($this->outputFilename);
  361. $zipFile->openFile($this->outputFilename);
  362. self::assertFalse(isset($zipFile[$oldName]));
  363. self::assertTrue(isset($zipFile[$newName]));
  364. self::assertFalse(isset($zipFile['file1.txt']));
  365. self::assertFalse(isset($zipFile['file2.txt']));
  366. self::assertFalse(isset($zipFile['file3.txt']));
  367. self::assertTrue(isset($zipFile['file_long_name.txt']));
  368. self::assertTrue(isset($zipFile['file4.txt']));
  369. self::assertTrue(isset($zipFile['fi.txt']));
  370. $zipFile->close();
  371. }
  372. /**
  373. * @expectedException \PhpZip\Exception\InvalidArgumentException
  374. * @expectedExceptionMessage name is null
  375. */
  376. public function testRenameEntryNull()
  377. {
  378. $zipFile = new ZipFile();
  379. $zipFile->rename(null, 'new-file');
  380. }
  381. /**
  382. * @expectedException \PhpZip\Exception\InvalidArgumentException
  383. * @expectedExceptionMessage name is null
  384. */
  385. public function testRenameEntryNull2()
  386. {
  387. $zipFile = new ZipFile();
  388. $zipFile->rename('old-file', null);
  389. }
  390. /**
  391. * @expectedException \PhpZip\Exception\InvalidArgumentException
  392. * @expectedExceptionMessage is exists
  393. */
  394. public function testRenameEntryNewEntyExists()
  395. {
  396. $zipFile = new ZipFile();
  397. $zipFile['file'] = 'content';
  398. $zipFile['file2'] = 'content 2';
  399. $zipFile->saveAsFile($this->outputFilename);
  400. $zipFile->close();
  401. $zipFile = new ZipFile();
  402. $zipFile->openFile($this->outputFilename);
  403. $zipFile->rename('file2', 'file');
  404. }
  405. /**
  406. * @expectedException \PhpZip\Exception\ZipNotFoundEntry
  407. */
  408. public function testRenameEntryNotFound()
  409. {
  410. $zipFile = new ZipFile();
  411. $zipFile['file'] = 'content';
  412. $zipFile['file2'] = 'content 2';
  413. $zipFile->saveAsFile($this->outputFilename);
  414. $zipFile->close();
  415. $zipFile = new ZipFile();
  416. $zipFile->openFile($this->outputFilename);
  417. $zipFile->rename('file2.bak', 'file3');
  418. }
  419. /**
  420. * Delete entry from name.
  421. */
  422. public function testDeleteFromName()
  423. {
  424. $inputDir = dirname(dirname(__DIR__)) . DIRECTORY_SEPARATOR;
  425. $deleteEntryName = 'composer.json';
  426. $zipFile = new ZipFile();
  427. $zipFile->addDir($inputDir);
  428. $zipFile->saveAsFile($this->outputFilename);
  429. $zipFile->close();
  430. self::assertCorrectZipArchive($this->outputFilename);
  431. $zipFile->openFile($this->outputFilename);
  432. $zipFile->deleteFromName($deleteEntryName);
  433. $zipFile->saveAsFile($this->outputFilename);
  434. $zipFile->close();
  435. self::assertCorrectZipArchive($this->outputFilename);
  436. $zipFile->openFile($this->outputFilename);
  437. self::assertFalse(isset($zipFile[$deleteEntryName]));
  438. $zipFile->close();
  439. }
  440. public function testDeleteNewEntry()
  441. {
  442. $zipFile = new ZipFile();
  443. $zipFile['entry1'] = '';
  444. $zipFile['entry2'] = '';
  445. $zipFile->deleteFromName('entry2');
  446. $zipFile->saveAsFile($this->outputFilename);
  447. $zipFile->close();
  448. $zipFile->openFile($this->outputFilename);
  449. self::assertEquals(sizeof($zipFile), 1);
  450. self::assertTrue(isset($zipFile['entry1']));
  451. self::assertFalse(isset($zipFile['entry2']));
  452. $zipFile->close();
  453. }
  454. /**
  455. * @expectedException \PhpZip\Exception\ZipNotFoundEntry
  456. */
  457. public function testDeleteFromNameNotFoundEntry()
  458. {
  459. $zipFile = new ZipFile();
  460. $zipFile->deleteFromName('entry');
  461. }
  462. /**
  463. * Delete zip entries from glob pattern
  464. */
  465. public function testDeleteFromGlob()
  466. {
  467. $inputDir = dirname(dirname(__DIR__));
  468. $zipFile = new ZipFile();
  469. $zipFile->addFilesFromGlobRecursive($inputDir, '**.{xml,json,md}', '/');
  470. self::assertTrue(isset($zipFile['composer.json']));
  471. self::assertTrue(isset($zipFile['phpunit.xml']));
  472. $zipFile->saveAsFile($this->outputFilename);
  473. $zipFile->close();
  474. self::assertCorrectZipArchive($this->outputFilename);
  475. $zipFile->openFile($this->outputFilename);
  476. self::assertTrue(isset($zipFile['composer.json']));
  477. self::assertTrue(isset($zipFile['phpunit.xml']));
  478. $zipFile->deleteFromGlob('**.{xml,json}');
  479. self::assertFalse(isset($zipFile['composer.json']));
  480. self::assertFalse(isset($zipFile['phpunit.xml']));
  481. $zipFile->saveAsFile($this->outputFilename);
  482. $zipFile->close();
  483. self::assertCorrectZipArchive($this->outputFilename);
  484. $zipFile->openFile($this->outputFilename);
  485. self::assertTrue($zipFile->count() > 0);
  486. foreach ($zipFile->getListFiles() as $name) {
  487. self::assertStringEndsWith('.md', $name);
  488. }
  489. $zipFile->close();
  490. }
  491. /**
  492. * @expectedException \PhpZip\Exception\InvalidArgumentException
  493. * @expectedExceptionMessage Glob pattern is empty
  494. */
  495. public function testDeleteFromGlobFailNull()
  496. {
  497. $zipFile = new ZipFile();
  498. $zipFile->deleteFromGlob(null);
  499. }
  500. /**
  501. * @expectedException \PhpZip\Exception\InvalidArgumentException
  502. * @expectedExceptionMessage Glob pattern is empty
  503. */
  504. public function testDeleteFromGlobFailEmpty()
  505. {
  506. $zipFile = new ZipFile();
  507. $zipFile->deleteFromGlob('');
  508. }
  509. /**
  510. * Delete entries from regex pattern
  511. */
  512. public function testDeleteFromRegex()
  513. {
  514. $inputDir = dirname(dirname(__DIR__));
  515. $zipFile = new ZipFile();
  516. $zipFile->addFilesFromRegexRecursive($inputDir, '~\.(xml|json)$~i', 'Path');
  517. $zipFile->saveAsFile($this->outputFilename);
  518. $zipFile->close();
  519. self::assertCorrectZipArchive($this->outputFilename);
  520. $zipFile->openFile($this->outputFilename);
  521. $zipFile->deleteFromRegex('~\.(json)$~i');
  522. $zipFile->addFromString('test.txt', 'content');
  523. $zipFile->deleteFromRegex('~\.txt$~');
  524. $zipFile->saveAsFile($this->outputFilename);
  525. $zipFile->close();
  526. self::assertCorrectZipArchive($this->outputFilename);
  527. $zipFile->openFile($this->outputFilename);
  528. self::assertFalse(isset($zipFile['Path/composer.json']));
  529. self::assertFalse(isset($zipFile['Path/test.txt']));
  530. self::assertTrue(isset($zipFile['Path/phpunit.xml']));
  531. $zipFile->close();
  532. }
  533. /**
  534. * @expectedException \PhpZip\Exception\InvalidArgumentException
  535. * @expectedExceptionMessage Regex pattern is empty.
  536. */
  537. public function testDeleteFromRegexFailNull()
  538. {
  539. $zipFile = new ZipFile();
  540. $zipFile->deleteFromRegex(null);
  541. }
  542. /**
  543. * @expectedException \PhpZip\Exception\InvalidArgumentException
  544. * @expectedExceptionMessage Regex pattern is empty.
  545. */
  546. public function testDeleteFromRegexFailEmpty()
  547. {
  548. $zipFile = new ZipFile();
  549. $zipFile->deleteFromRegex('');
  550. }
  551. /**
  552. * Delete all entries
  553. */
  554. public function testDeleteAll()
  555. {
  556. $zipFile = new ZipFile();
  557. $zipFile->addDirRecursive(dirname(dirname(__DIR__)) .DIRECTORY_SEPARATOR. 'src');
  558. self::assertTrue($zipFile->count() > 0);
  559. $zipFile->saveAsFile($this->outputFilename);
  560. $zipFile->close();
  561. self::assertCorrectZipArchive($this->outputFilename);
  562. $zipFile->openFile($this->outputFilename);
  563. self::assertTrue($zipFile->count() > 0);
  564. $zipFile->deleteAll();
  565. $zipFile->saveAsFile($this->outputFilename);
  566. $zipFile->close();
  567. self::assertCorrectEmptyZip($this->outputFilename);
  568. $zipFile->openFile($this->outputFilename);
  569. self::assertEquals($zipFile->count(), 0);
  570. $zipFile->close();
  571. }
  572. /**
  573. * Test zip archive comment.
  574. */
  575. public function testArchiveComment()
  576. {
  577. $comment = "This zip file comment" . PHP_EOL
  578. . "Αυτό το σχόλιο αρχείο zip" . PHP_EOL
  579. . "Это комментарий zip архива" . PHP_EOL
  580. . "這個ZIP文件註釋" . PHP_EOL
  581. . "ეს zip ფაილის კომენტარი" . PHP_EOL
  582. . "このzipファイルにコメント" . PHP_EOL
  583. . "ความคิดเห็นนี้ไฟล์ซิป";
  584. $zipFile = new ZipFile();
  585. $zipFile->setArchiveComment($comment);
  586. $zipFile->addFile(__FILE__);
  587. $zipFile->saveAsFile($this->outputFilename);
  588. $zipFile->close();
  589. self::assertCorrectZipArchive($this->outputFilename);
  590. $zipFile->openFile($this->outputFilename);
  591. self::assertEquals($zipFile->getArchiveComment(), $comment);
  592. $zipFile->setArchiveComment(null); // remove archive comment
  593. $zipFile->saveAsFile($this->outputFilename);
  594. $zipFile->close();
  595. self::assertCorrectZipArchive($this->outputFilename);
  596. // check empty comment
  597. $zipFile->openFile($this->outputFilename);
  598. self::assertEquals($zipFile->getArchiveComment(), "");
  599. $zipFile->close();
  600. }
  601. /**
  602. * Test very long archive comment.
  603. *
  604. * @expectedException \PhpZip\Exception\InvalidArgumentException
  605. */
  606. public function testVeryLongArchiveComment()
  607. {
  608. $comment = "Very long comment" . PHP_EOL .
  609. "Очень длинный комментарий" . PHP_EOL;
  610. $comment = str_repeat($comment, ceil(0xffff / strlen($comment)) + strlen($comment) + 1);
  611. $zipFile = new ZipFile();
  612. $zipFile->setArchiveComment($comment);
  613. }
  614. /**
  615. * Test zip entry comment.
  616. */
  617. public function testEntryComment()
  618. {
  619. $entries = [
  620. '文件1.txt' => [
  621. 'data' => CryptoUtil::randomBytes(255),
  622. 'comment' => "這是註釋的條目。",
  623. ],
  624. 'file2.txt' => [
  625. 'data' => CryptoUtil::randomBytes(255),
  626. 'comment' => null
  627. ],
  628. 'file3.txt' => [
  629. 'data' => CryptoUtil::randomBytes(255),
  630. 'comment' => CryptoUtil::randomBytes(255),
  631. ],
  632. 'file4.txt' => [
  633. 'data' => CryptoUtil::randomBytes(255),
  634. 'comment' => "Комментарий файла"
  635. ],
  636. 'file5.txt' => [
  637. 'data' => CryptoUtil::randomBytes(255),
  638. 'comment' => "ไฟล์แสดงความคิดเห็น"
  639. ],
  640. 'file6 emoji 🙍🏼.txt' => [
  641. 'data' => CryptoUtil::randomBytes(255),
  642. 'comment' => "Emoji comment file - 😀 ⛈ ❤️ 🤴🏽"
  643. ],
  644. ];
  645. // create archive with entry comments
  646. $zipFile = new ZipFile();
  647. foreach ($entries as $entryName => $item) {
  648. $zipFile->addFromString($entryName, $item['data']);
  649. $zipFile->setEntryComment($entryName, $item['comment']);
  650. }
  651. $zipFile->saveAsFile($this->outputFilename);
  652. $zipFile->close();
  653. self::assertCorrectZipArchive($this->outputFilename);
  654. // check and modify comments
  655. $zipFile->openFile($this->outputFilename);
  656. foreach ($zipFile->getListFiles() as $entryName) {
  657. $entriesItem = $entries[$entryName];
  658. self::assertNotEmpty($entriesItem);
  659. self::assertEquals($zipFile[$entryName], $entriesItem['data']);
  660. self::assertEquals($zipFile->getEntryComment($entryName), (string)$entriesItem['comment']);
  661. }
  662. // modify comment
  663. $entries['file5.txt']['comment'] = mt_rand(1, 100000000);
  664. $zipFile->setEntryComment('file5.txt', $entries['file5.txt']['comment']);
  665. $zipFile->saveAsFile($this->outputFilename);
  666. $zipFile->close();
  667. self::assertCorrectZipArchive($this->outputFilename);
  668. // check modify comments
  669. $zipFile->openFile($this->outputFilename);
  670. foreach ($entries as $entryName => $entriesItem) {
  671. self::assertTrue(isset($zipFile[$entryName]));
  672. self::assertEquals($zipFile->getEntryComment($entryName), (string)$entriesItem['comment']);
  673. self::assertEquals($zipFile[$entryName], $entriesItem['data']);
  674. }
  675. $zipFile->close();
  676. }
  677. /**
  678. * Test zip entry very long comment.
  679. *
  680. * @expectedException \PhpZip\Exception\ZipException
  681. * @expectedExceptionMessage Comment too long
  682. */
  683. public function testVeryLongEntryComment()
  684. {
  685. $comment = "Very long comment" . PHP_EOL .
  686. "Очень длинный комментарий" . PHP_EOL;
  687. $comment = str_repeat($comment, ceil(0xffff / strlen($comment)) + strlen($comment) + 1);
  688. $zipFile = new ZipFile();
  689. $zipFile->addFile(__FILE__, 'test');
  690. $zipFile->setEntryComment('test', $comment);
  691. }
  692. /**
  693. * @expectedException \PhpZip\Exception\ZipNotFoundEntry
  694. */
  695. public function testSetEntryCommentNotFoundEntry()
  696. {
  697. $zipFile = new ZipFile();
  698. $zipFile->setEntryComment('test', 'comment');
  699. }
  700. /**
  701. * Test all available support compression methods.
  702. */
  703. public function testCompressionMethod()
  704. {
  705. $entries = [
  706. '1' => [
  707. 'data' => CryptoUtil::randomBytes(255),
  708. 'method' => ZipFileInterface::METHOD_STORED,
  709. 'expected' => 'No compression',
  710. ],
  711. '2' => [
  712. 'data' => CryptoUtil::randomBytes(255),
  713. 'method' => ZipFileInterface::METHOD_DEFLATED,
  714. 'expected' => 'Deflate',
  715. ],
  716. ];
  717. if (extension_loaded("bz2")) {
  718. $entries['3'] = [
  719. 'data' => CryptoUtil::randomBytes(255),
  720. 'method' => ZipFileInterface::METHOD_BZIP2,
  721. 'expected' => 'Bzip2',
  722. ];
  723. }
  724. $zipFile = new ZipFile();
  725. foreach ($entries as $entryName => $item) {
  726. $zipFile->addFromString($entryName, $item['data'], $item['method']);
  727. }
  728. $zipFile->saveAsFile($this->outputFilename);
  729. $zipFile->close();
  730. self::assertCorrectZipArchive($this->outputFilename);
  731. $zipFile->openFile($this->outputFilename);
  732. $zipFile->setCompressionLevel(ZipFileInterface::LEVEL_BEST_COMPRESSION);
  733. $zipAllInfo = $zipFile->getAllInfo();
  734. foreach ($zipAllInfo as $entryName => $info) {
  735. self::assertEquals($zipFile[$entryName], $entries[$entryName]['data']);
  736. self::assertEquals($info->getMethodName(), $entries[$entryName]['expected']);
  737. $entryInfo = $zipFile->getEntryInfo($entryName);
  738. self::assertEquals($entryInfo, $info);
  739. }
  740. $zipFile->close();
  741. }
  742. /**
  743. * @expectedException \PhpZip\Exception\InvalidArgumentException
  744. * @expectedExceptionMessage Invalid compression level. Minimum level -1. Maximum level 9
  745. */
  746. public function testSetInvalidCompressionLevel()
  747. {
  748. $zipFile = new ZipFile();
  749. $zipFile->setCompressionLevel(-2);
  750. }
  751. /**
  752. * /**
  753. * @expectedException \PhpZip\Exception\InvalidArgumentException
  754. * @expectedExceptionMessage Invalid compression level. Minimum level -1. Maximum level 9
  755. */
  756. public function testSetInvalidCompressionLevel2()
  757. {
  758. $zipFile = new ZipFile();
  759. $zipFile->setCompressionLevel(10);
  760. }
  761. /**
  762. * Test extract all files.
  763. */
  764. public function testExtract()
  765. {
  766. $entries = [
  767. 'test1.txt' => CryptoUtil::randomBytes(255),
  768. 'test2.txt' => CryptoUtil::randomBytes(255),
  769. 'test/test 2/test3.txt' => CryptoUtil::randomBytes(255),
  770. 'test empty/dir' => null,
  771. ];
  772. $zipFile = new ZipFile();
  773. foreach ($entries as $entryName => $value) {
  774. if ($value === null) {
  775. $zipFile->addEmptyDir($entryName);
  776. } else {
  777. $zipFile->addFromString($entryName, $value);
  778. }
  779. }
  780. $zipFile->saveAsFile($this->outputFilename);
  781. $zipFile->close();
  782. self::assertTrue(mkdir($this->outputDirname, 0755, true));
  783. $zipFile->openFile($this->outputFilename);
  784. $zipFile->extractTo($this->outputDirname);
  785. foreach ($entries as $entryName => $value) {
  786. $fullExtractedFilename = $this->outputDirname . DIRECTORY_SEPARATOR . $entryName;
  787. if ($value === null) {
  788. self::assertTrue(is_dir($fullExtractedFilename));
  789. self::assertTrue(FilesUtil::isEmptyDir($fullExtractedFilename));
  790. } else {
  791. self::assertTrue(is_file($fullExtractedFilename));
  792. $contents = file_get_contents($fullExtractedFilename);
  793. self::assertEquals($contents, $value);
  794. }
  795. }
  796. $zipFile->close();
  797. }
  798. /**
  799. * Test extract some files
  800. */
  801. public function testExtractSomeFiles()
  802. {
  803. $entries = [
  804. 'test1.txt' => CryptoUtil::randomBytes(255),
  805. 'test2.txt' => CryptoUtil::randomBytes(255),
  806. 'test3.txt' => CryptoUtil::randomBytes(255),
  807. 'test4.txt' => CryptoUtil::randomBytes(255),
  808. 'test5.txt' => CryptoUtil::randomBytes(255),
  809. 'test/test/test.txt' => CryptoUtil::randomBytes(255),
  810. 'test/test/test 2.txt' => CryptoUtil::randomBytes(255),
  811. 'test empty/dir/' => null,
  812. 'test empty/dir2/' => null,
  813. ];
  814. $extractEntries = [
  815. 'test1.txt',
  816. 'test3.txt',
  817. 'test5.txt',
  818. 'test/test/test 2.txt',
  819. 'test empty/dir2/'
  820. ];
  821. self::assertTrue(mkdir($this->outputDirname, 0755, true));
  822. $zipFile = new ZipFile();
  823. $zipFile->addAll($entries);
  824. $zipFile->saveAsFile($this->outputFilename);
  825. $zipFile->close();
  826. $zipFile->openFile($this->outputFilename);
  827. $zipFile->extractTo($this->outputDirname, $extractEntries);
  828. foreach ($entries as $entryName => $value) {
  829. $fullExtractFilename = $this->outputDirname . DIRECTORY_SEPARATOR . $entryName;
  830. if (in_array($entryName, $extractEntries)) {
  831. if ($value === null) {
  832. self::assertTrue(is_dir($fullExtractFilename));
  833. self::assertTrue(FilesUtil::isEmptyDir($fullExtractFilename));
  834. } else {
  835. self::assertTrue(is_file($fullExtractFilename));
  836. $contents = file_get_contents($fullExtractFilename);
  837. self::assertEquals($contents, $value);
  838. }
  839. } else {
  840. if ($value === null) {
  841. self::assertFalse(is_dir($fullExtractFilename));
  842. } else {
  843. self::assertFalse(is_file($fullExtractFilename));
  844. }
  845. }
  846. }
  847. self::assertFalse(is_file($this->outputDirname . DIRECTORY_SEPARATOR . 'test/test/test.txt'));
  848. $zipFile->extractTo($this->outputDirname, 'test/test/test.txt');
  849. self::assertTrue(is_file($this->outputDirname . DIRECTORY_SEPARATOR . 'test/test/test.txt'));
  850. $zipFile->close();
  851. }
  852. /**
  853. * @expectedException \PhpZip\Exception\ZipException
  854. * @expectedExceptionMessage not found
  855. */
  856. public function testExtractFail()
  857. {
  858. $zipFile = new ZipFile();
  859. $zipFile['file'] = 'content';
  860. $zipFile->saveAsFile($this->outputFilename);
  861. $zipFile->close();
  862. $zipFile->openFile($this->outputFilename);
  863. $zipFile->extractTo('path/to/path');
  864. }
  865. /**
  866. * @expectedException \PhpZip\Exception\ZipException
  867. * @expectedExceptionMessage Destination is not directory
  868. */
  869. public function testExtractFail2()
  870. {
  871. $zipFile = new ZipFile();
  872. $zipFile['file'] = 'content';
  873. $zipFile->saveAsFile($this->outputFilename);
  874. $zipFile->close();
  875. $zipFile->openFile($this->outputFilename);
  876. $zipFile->extractTo($this->outputFilename);
  877. }
  878. /**
  879. * @expectedException \PhpZip\Exception\ZipException
  880. * @expectedExceptionMessage Destination is not writable directory
  881. */
  882. public function testExtractFail3()
  883. {
  884. if (0 === posix_getuid()) {
  885. $this->markTestSkipped('Skip the test for a user with root privileges');
  886. }
  887. $zipFile = new ZipFile();
  888. $zipFile['file'] = 'content';
  889. $zipFile->saveAsFile($this->outputFilename);
  890. $zipFile->close();
  891. self::assertTrue(mkdir($this->outputDirname, 0444, true));
  892. self::assertTrue(chmod($this->outputDirname, 0444));
  893. $zipFile->openFile($this->outputFilename);
  894. $zipFile->extractTo($this->outputDirname);
  895. }
  896. /**
  897. * @expectedException \PhpZip\Exception\InvalidArgumentException
  898. * @expectedExceptionMessage entryName is null
  899. */
  900. public function testAddFromArrayAccessNullName()
  901. {
  902. $zipFile = new ZipFile();
  903. $zipFile[null] = 'content';
  904. }
  905. /**
  906. * @expectedException \PhpZip\Exception\InvalidArgumentException
  907. * @expectedExceptionMessage entryName is empty
  908. */
  909. public function testAddFromArrayAccessEmptyName()
  910. {
  911. $zipFile = new ZipFile();
  912. $zipFile[''] = 'content';
  913. }
  914. /**
  915. * @expectedException \PhpZip\Exception\InvalidArgumentException
  916. * @expectedExceptionMessage Contents is null
  917. */
  918. public function testAddFromStringNullContents()
  919. {
  920. $zipFile = new ZipFile();
  921. $zipFile->addFromString('file', null);
  922. }
  923. /**
  924. * @expectedException \PhpZip\Exception\InvalidArgumentException
  925. * @expectedExceptionMessage Incorrect entry name
  926. */
  927. public function testAddFromStringNullEntryName()
  928. {
  929. $zipFile = new ZipFile();
  930. $zipFile->addFromString(null, 'contents');
  931. }
  932. /**
  933. * @expectedException \PhpZip\Exception\ZipUnsupportMethod
  934. * @expectedExceptionMessage Unsupported compression method
  935. */
  936. public function testAddFromStringUnsupportedMethod()
  937. {
  938. $zipFile = new ZipFile();
  939. $zipFile->addFromString('file', 'contents', ZipEntry::METHOD_WINZIP_AES);
  940. }
  941. /**
  942. * @expectedException \PhpZip\Exception\InvalidArgumentException
  943. * @expectedExceptionMessage Incorrect entry name
  944. */
  945. public function testAddFromStringEmptyEntryName()
  946. {
  947. $zipFile = new ZipFile();
  948. $zipFile->addFromString('', 'contents');
  949. }
  950. /**
  951. * Test compression method from add string.
  952. */
  953. public function testAddFromStringCompressionMethod()
  954. {
  955. $fileStored = sys_get_temp_dir() . '/zip-stored.txt';
  956. $fileDeflated = sys_get_temp_dir() . '/zip-deflated.txt';
  957. self::assertNotFalse(file_put_contents($fileStored, 'content'));
  958. self::assertNotFalse(file_put_contents($fileDeflated, str_repeat('content', 200)));
  959. $zipFile = new ZipFile();
  960. $zipFile->addFromString(basename($fileStored), file_get_contents($fileStored));
  961. $zipFile->addFromString(basename($fileDeflated), file_get_contents($fileDeflated));
  962. $zipFile->saveAsFile($this->outputFilename);
  963. $zipFile->close();
  964. unlink($fileStored);
  965. unlink($fileDeflated);
  966. $zipFile->openFile($this->outputFilename);
  967. $infoStored = $zipFile->getEntryInfo(basename($fileStored));
  968. $infoDeflated = $zipFile->getEntryInfo(basename($fileDeflated));
  969. self::assertEquals($infoStored->getMethodName(), 'No compression');
  970. self::assertEquals($infoDeflated->getMethodName(), 'Deflate');
  971. $zipFile->close();
  972. }
  973. /**
  974. * @expectedException \PhpZip\Exception\InvalidArgumentException
  975. * @expectedExceptionMessage stream is not resource
  976. */
  977. public function testAddFromStreamInvalidResource()
  978. {
  979. $zipFile = new ZipFile();
  980. /** @noinspection PhpParamsInspection */
  981. $zipFile->addFromStream("invalid resource", "name");
  982. }
  983. /**
  984. * @expectedException \PhpZip\Exception\InvalidArgumentException
  985. * @expectedExceptionMessage Incorrect entry name
  986. */
  987. public function testAddFromStreamEmptyEntryName()
  988. {
  989. $handle = fopen(__FILE__, 'rb');
  990. $zipFile = new ZipFile();
  991. $zipFile->addFromStream($handle, "");
  992. }
  993. /**
  994. * @expectedException \PhpZip\Exception\ZipUnsupportMethod
  995. * @expectedExceptionMessage Unsupported method
  996. */
  997. public function testAddFromStreamUnsupportedMethod()
  998. {
  999. $handle = fopen(__FILE__, 'rb');
  1000. $zipFile = new ZipFile();
  1001. $zipFile->addFromStream($handle, basename(__FILE__), ZipEntry::METHOD_WINZIP_AES);
  1002. }
  1003. /**
  1004. * Test compression method from add stream.
  1005. */
  1006. public function testAddFromStreamCompressionMethod()
  1007. {
  1008. $fileStored = sys_get_temp_dir() . '/zip-stored.txt';
  1009. $fileDeflated = sys_get_temp_dir() . '/zip-deflated.txt';
  1010. self::assertNotFalse(file_put_contents($fileStored, 'content'));
  1011. self::assertNotFalse(file_put_contents($fileDeflated, str_repeat('content', 200)));
  1012. $fpStored = fopen($fileStored, 'rb');
  1013. $fpDeflated = fopen($fileDeflated, 'rb');
  1014. $zipFile = new ZipFile();
  1015. $zipFile->addFromStream($fpStored, basename($fileStored));
  1016. $zipFile->addFromStream($fpDeflated, basename($fileDeflated));
  1017. $zipFile->saveAsFile($this->outputFilename);
  1018. $zipFile->close();
  1019. unlink($fileStored);
  1020. unlink($fileDeflated);
  1021. $zipFile->openFile($this->outputFilename);
  1022. $infoStored = $zipFile->getEntryInfo(basename($fileStored));
  1023. $infoDeflated = $zipFile->getEntryInfo(basename($fileDeflated));
  1024. self::assertEquals($infoStored->getMethodName(), 'No compression');
  1025. self::assertEquals($infoDeflated->getMethodName(), 'Deflate');
  1026. $zipFile->close();
  1027. }
  1028. /**
  1029. * @expectedException \PhpZip\Exception\InvalidArgumentException
  1030. * @expectedExceptionMessage Filename is null
  1031. */
  1032. public function testAddFileNullFileName()
  1033. {
  1034. $zipFile = new ZipFile();
  1035. $zipFile->addFile(null);
  1036. }
  1037. /**
  1038. * @expectedException \PhpZip\Exception\InvalidArgumentException
  1039. * @expectedExceptionMessage is not exists
  1040. */
  1041. public function testAddFileCantExists()
  1042. {
  1043. $zipFile = new ZipFile();
  1044. $zipFile->addFile('path/to/file');
  1045. }
  1046. /**
  1047. * @expectedException \PhpZip\Exception\ZipUnsupportMethod
  1048. * @expectedExceptionMessage Unsupported method
  1049. */
  1050. public function testAddFileUnsupportedMethod()
  1051. {
  1052. $zipFile = new ZipFile();
  1053. $zipFile->addFile(__FILE__, null, ZipEntry::METHOD_WINZIP_AES);
  1054. }
  1055. /**
  1056. * @expectedException \PhpZip\Exception\InvalidArgumentException
  1057. * @expectedExceptionMessage can not open
  1058. */
  1059. public function testAddFileCantOpen()
  1060. {
  1061. if (0 === posix_getuid()) {
  1062. $this->markTestSkipped('Skip the test for a user with root privileges');
  1063. }
  1064. self::assertNotFalse(file_put_contents($this->outputFilename, ''));
  1065. self::assertTrue(chmod($this->outputFilename, 0244));
  1066. $zipFile = new ZipFile();
  1067. $zipFile->addFile($this->outputFilename);
  1068. }
  1069. /**
  1070. * @expectedException \PhpZip\Exception\InvalidArgumentException
  1071. * @expectedExceptionMessage Input dir empty
  1072. */
  1073. public function testAddDirNullDirname()
  1074. {
  1075. $zipFile = new ZipFile();
  1076. $zipFile->addDir(null);
  1077. }
  1078. /**
  1079. * @expectedException \PhpZip\Exception\InvalidArgumentException
  1080. * @expectedExceptionMessage Input dir empty
  1081. */
  1082. public function testAddDirEmptyDirname()
  1083. {
  1084. $zipFile = new ZipFile();
  1085. $zipFile->addDir("");
  1086. }
  1087. /**
  1088. * @expectedException \PhpZip\Exception\InvalidArgumentException
  1089. * @expectedExceptionMessage can't exists
  1090. */
  1091. public function testAddDirCantExists()
  1092. {
  1093. $zipFile = new ZipFile();
  1094. $zipFile->addDir(uniqid());
  1095. }
  1096. /**
  1097. * @expectedException \PhpZip\Exception\InvalidArgumentException
  1098. * @expectedExceptionMessage Input dir empty
  1099. */
  1100. public function testAddDirRecursiveNullDirname()
  1101. {
  1102. $zipFile = new ZipFile();
  1103. $zipFile->addDirRecursive(null);
  1104. }
  1105. /**
  1106. * @expectedException \PhpZip\Exception\InvalidArgumentException
  1107. * @expectedExceptionMessage Input dir empty
  1108. */
  1109. public function testAddDirRecursiveEmptyDirname()
  1110. {
  1111. $zipFile = new ZipFile();
  1112. $zipFile->addDirRecursive("");
  1113. }
  1114. /**
  1115. * @expectedException \PhpZip\Exception\InvalidArgumentException
  1116. * @expectedExceptionMessage can't exists
  1117. */
  1118. public function testAddDirRecursiveCantExists()
  1119. {
  1120. $zipFile = new ZipFile();
  1121. $zipFile->addDirRecursive(uniqid());
  1122. }
  1123. /**
  1124. * @expectedException \PhpZip\Exception\InvalidArgumentException
  1125. * @expectedExceptionMessage Input dir empty
  1126. */
  1127. public function testAddFilesFromGlobNull()
  1128. {
  1129. $zipFile = new ZipFile();
  1130. $zipFile->addFilesFromGlob(null, '*.png');
  1131. }
  1132. /**
  1133. * @expectedException \PhpZip\Exception\InvalidArgumentException
  1134. * @expectedExceptionMessage Input dir empty
  1135. */
  1136. public function testAddFilesFromGlobEmpty()
  1137. {
  1138. $zipFile = new ZipFile();
  1139. $zipFile->addFilesFromGlob("", '*.png');
  1140. }
  1141. /**
  1142. * @expectedException \PhpZip\Exception\InvalidArgumentException
  1143. * @expectedExceptionMessage can't exists
  1144. */
  1145. public function testAddFilesFromGlobCantExists()
  1146. {
  1147. $zipFile = new ZipFile();
  1148. $zipFile->addFilesFromGlob("path/to/path", '*.png');
  1149. }
  1150. /**
  1151. * @expectedException \PhpZip\Exception\InvalidArgumentException
  1152. * @expectedExceptionMessage glob pattern empty
  1153. */
  1154. public function testAddFilesFromGlobNullPattern()
  1155. {
  1156. $zipFile = new ZipFile();
  1157. $zipFile->addFilesFromGlob(__DIR__, null);
  1158. }
  1159. /**
  1160. * @expectedException \PhpZip\Exception\InvalidArgumentException
  1161. * @expectedExceptionMessage glob pattern empty
  1162. */
  1163. public function testAddFilesFromGlobEmptyPattern()
  1164. {
  1165. $zipFile = new ZipFile();
  1166. $zipFile->addFilesFromGlob(__DIR__, '');
  1167. }
  1168. /**
  1169. * @expectedException \PhpZip\Exception\InvalidArgumentException
  1170. * @expectedExceptionMessage Input dir empty
  1171. */
  1172. public function testAddFilesFromGlobRecursiveNull()
  1173. {
  1174. $zipFile = new ZipFile();
  1175. $zipFile->addFilesFromGlobRecursive(null, '*.png');
  1176. }
  1177. /**
  1178. * @expectedException \PhpZip\Exception\InvalidArgumentException
  1179. * @expectedExceptionMessage Input dir empty
  1180. */
  1181. public function testAddFilesFromGlobRecursiveEmpty()
  1182. {
  1183. $zipFile = new ZipFile();
  1184. $zipFile->addFilesFromGlobRecursive("", '*.png');
  1185. }
  1186. /**
  1187. * @expectedException \PhpZip\Exception\InvalidArgumentException
  1188. * @expectedExceptionMessage can't exists
  1189. */
  1190. public function testAddFilesFromGlobRecursiveCantExists()
  1191. {
  1192. $zipFile = new ZipFile();
  1193. $zipFile->addFilesFromGlobRecursive("path/to/path", '*.png');
  1194. }
  1195. /**
  1196. * @expectedException \PhpZip\Exception\InvalidArgumentException
  1197. * @expectedExceptionMessage glob pattern empty
  1198. */
  1199. public function testAddFilesFromGlobRecursiveNullPattern()
  1200. {
  1201. $zipFile = new ZipFile();
  1202. $zipFile->addFilesFromGlobRecursive(__DIR__, null);
  1203. }
  1204. /**
  1205. * @expectedException \PhpZip\Exception\InvalidArgumentException
  1206. * @expectedExceptionMessage glob pattern empty
  1207. */
  1208. public function testAddFilesFromGlobRecursiveEmptyPattern()
  1209. {
  1210. $zipFile = new ZipFile();
  1211. $zipFile->addFilesFromGlobRecursive(__DIR__, '');
  1212. }
  1213. /**
  1214. * @expectedException \PhpZip\Exception\InvalidArgumentException
  1215. * @expectedExceptionMessage Input dir empty
  1216. */
  1217. public function testAddFilesFromRegexDirectoryNull()
  1218. {
  1219. $zipFile = new ZipFile();
  1220. $zipFile->addFilesFromRegex(null, '~\.png$~i');
  1221. }
  1222. /**
  1223. * @expectedException \PhpZip\Exception\InvalidArgumentException
  1224. * @expectedExceptionMessage Input dir empty
  1225. */
  1226. public function testAddFilesFromRegexDirectoryEmpty()
  1227. {
  1228. $zipFile = new ZipFile();
  1229. $zipFile->addFilesFromRegex("", '~\.png$~i');
  1230. }
  1231. /**
  1232. * @expectedException \PhpZip\Exception\InvalidArgumentException
  1233. * @expectedExceptionMessage can't exists
  1234. */
  1235. public function testAddFilesFromRegexCantExists()
  1236. {
  1237. $zipFile = new ZipFile();
  1238. $zipFile->addFilesFromRegex("path/to/path", '~\.png$~i');
  1239. }
  1240. /**
  1241. * @expectedException \PhpZip\Exception\InvalidArgumentException
  1242. * @expectedExceptionMessage regex pattern empty
  1243. */
  1244. public function testAddFilesFromRegexNullPattern()
  1245. {
  1246. $zipFile = new ZipFile();
  1247. $zipFile->addFilesFromRegex(__DIR__, null);
  1248. }
  1249. /**
  1250. * @expectedException \PhpZip\Exception\InvalidArgumentException
  1251. * @expectedExceptionMessage regex pattern empty
  1252. */
  1253. public function testAddFilesFromRegexEmptyPattern()
  1254. {
  1255. $zipFile = new ZipFile();
  1256. $zipFile->addFilesFromRegex(__DIR__, '');
  1257. }
  1258. /**
  1259. * @expectedException \PhpZip\Exception\InvalidArgumentException
  1260. * @expectedExceptionMessage Input dir empty
  1261. */
  1262. public function testAddFilesFromRegexRecursiveDirectoryNull()
  1263. {
  1264. $zipFile = new ZipFile();
  1265. $zipFile->addFilesFromRegexRecursive(null, '~\.png$~i');
  1266. }
  1267. /**
  1268. * @expectedException \PhpZip\Exception\InvalidArgumentException
  1269. * @expectedExceptionMessage Input dir empty
  1270. */
  1271. public function testAddFilesFromRegexRecursiveEmpty()
  1272. {
  1273. $zipFile = new ZipFile();
  1274. $zipFile->addFilesFromRegexRecursive("", '~\.png$~i');
  1275. }
  1276. /**
  1277. * @expectedException \PhpZip\Exception\InvalidArgumentException
  1278. * @expectedExceptionMessage can't exists
  1279. */
  1280. public function testAddFilesFromRegexRecursiveCantExists()
  1281. {
  1282. $zipFile = new ZipFile();
  1283. $zipFile->addFilesFromGlobRecursive("path/to/path", '~\.png$~i');
  1284. }
  1285. /**
  1286. * @expectedException \PhpZip\Exception\InvalidArgumentException
  1287. * @expectedExceptionMessage regex pattern empty
  1288. */
  1289. public function testAddFilesFromRegexRecursiveNullPattern()
  1290. {
  1291. $zipFile = new ZipFile();
  1292. $zipFile->addFilesFromRegexRecursive(__DIR__, null);
  1293. }
  1294. /**
  1295. * @expectedException \PhpZip\Exception\InvalidArgumentException
  1296. * @expectedExceptionMessage regex pattern empty
  1297. */
  1298. public function testAddFilesFromRegexRecursiveEmptyPattern()
  1299. {
  1300. $zipFile = new ZipFile();
  1301. $zipFile->addFilesFromRegexRecursive(__DIR__, '');
  1302. }
  1303. /**
  1304. * @expectedException \PhpZip\Exception\InvalidArgumentException
  1305. * @expectedExceptionMessage handle is not resource
  1306. */
  1307. public function testSaveAsStreamBadStream()
  1308. {
  1309. $zipFile = new ZipFile();
  1310. /** @noinspection PhpParamsInspection */
  1311. $zipFile->saveAsStream("bad stream");
  1312. }
  1313. /**
  1314. * @expectedException \PhpZip\Exception\InvalidArgumentException
  1315. * @expectedExceptionMessage can not open from write
  1316. */
  1317. public function testSaveAsFileNotWritable()
  1318. {
  1319. if (0 === posix_getuid()) {
  1320. $this->markTestSkipped('Skip the test for a user with root privileges');
  1321. }
  1322. self::assertTrue(mkdir($this->outputDirname, 0444, true));
  1323. self::assertTrue(chmod($this->outputDirname, 0444));
  1324. $this->outputFilename = $this->outputDirname . DIRECTORY_SEPARATOR . basename($this->outputFilename);
  1325. $zipFile = new ZipFile();
  1326. $zipFile->saveAsFile($this->outputFilename);
  1327. }
  1328. /**
  1329. * Test `ZipFile` implemented \ArrayAccess, \Countable and |iterator.
  1330. */
  1331. public function testZipFileArrayAccessAndCountableAndIterator()
  1332. {
  1333. $files = [];
  1334. $numFiles = mt_rand(20, 100);
  1335. for ($i = 0; $i < $numFiles; $i++) {
  1336. $files['file' . $i . '.txt'] = CryptoUtil::randomBytes(255);
  1337. }
  1338. $methods = [ZipFileInterface::METHOD_STORED, ZipFileInterface::METHOD_DEFLATED];
  1339. if (extension_loaded("bz2")) {
  1340. $methods[] = ZipFileInterface::METHOD_BZIP2;
  1341. }
  1342. $zipFile = new ZipFile();
  1343. $zipFile->setCompressionLevel(ZipFileInterface::LEVEL_BEST_SPEED);
  1344. foreach ($files as $entryName => $content) {
  1345. $zipFile->addFromString($entryName, $content, $methods[array_rand($methods)]);
  1346. }
  1347. $zipFile->saveAsFile($this->outputFilename);
  1348. $zipFile->close();
  1349. self::assertCorrectZipArchive($this->outputFilename);
  1350. $zipFile->openFile($this->outputFilename);
  1351. // Test \Countable
  1352. self::assertEquals($zipFile->count(), $numFiles);
  1353. self::assertEquals(count($zipFile), $numFiles);
  1354. // Test \ArrayAccess
  1355. reset($files);
  1356. foreach ($zipFile as $entryName => $content) {
  1357. self::assertEquals($entryName, key($files));
  1358. self::assertEquals($content, current($files));
  1359. next($files);
  1360. }
  1361. // Test \Iterator
  1362. reset($files);
  1363. $iterator = new \ArrayIterator($zipFile);
  1364. $iterator->rewind();
  1365. while ($iterator->valid()) {
  1366. $key = $iterator->key();
  1367. $value = $iterator->current();
  1368. self::assertEquals($key, key($files));
  1369. self::assertEquals($value, current($files));
  1370. next($files);
  1371. $iterator->next();
  1372. }
  1373. $zipFile->close();
  1374. $zipFile = new ZipFile();
  1375. $zipFile['file1.txt'] = 'content 1';
  1376. $zipFile['dir/file2.txt'] = 'content 1';
  1377. $zipFile['dir/empty dir/'] = null;
  1378. $zipFile->saveAsFile($this->outputFilename);
  1379. $zipFile->close();
  1380. self::assertCorrectZipArchive($this->outputFilename);
  1381. $zipFile->openFile($this->outputFilename);
  1382. self::assertTrue(isset($zipFile['file1.txt']));
  1383. self::assertTrue(isset($zipFile['dir/file2.txt']));
  1384. self::assertTrue(isset($zipFile['dir/empty dir/']));
  1385. self::assertFalse(isset($zipFile['dir/empty dir/2/']));
  1386. $zipFile['dir/empty dir/2/'] = null;
  1387. unset($zipFile['dir/file2.txt'], $zipFile['dir/empty dir/']);
  1388. $zipFile->saveAsFile($this->outputFilename);
  1389. $zipFile->close();
  1390. self::assertCorrectZipArchive($this->outputFilename);
  1391. $zipFile->openFile($this->outputFilename);
  1392. self::assertTrue(isset($zipFile['file1.txt']));
  1393. self::assertFalse(isset($zipFile['dir/file2.txt']));
  1394. self::assertFalse(isset($zipFile['dir/empty dir/']));
  1395. self::assertTrue(isset($zipFile['dir/empty dir/2/']));
  1396. $zipFile->close();
  1397. }
  1398. public function testArrayAccessAddFile()
  1399. {
  1400. $entryName = 'path/to/file.dat';
  1401. $entryNameStream = 'path/to/' . basename(__FILE__);
  1402. $zipFile = new ZipFile();
  1403. $zipFile[$entryName] = new \SplFileInfo(__FILE__);
  1404. $zipFile[$entryNameStream] = fopen(__FILE__, 'r');
  1405. $zipFile->saveAsFile($this->outputFilename);
  1406. $zipFile->close();
  1407. self::assertCorrectZipArchive($this->outputFilename);
  1408. $zipFile->openFile($this->outputFilename);
  1409. self::assertEquals(sizeof($zipFile), 2);
  1410. self::assertTrue(isset($zipFile[$entryName]));
  1411. self::assertTrue(isset($zipFile[$entryNameStream]));
  1412. self::assertEquals($zipFile[$entryName], file_get_contents(__FILE__));
  1413. self::assertEquals($zipFile[$entryNameStream], file_get_contents(__FILE__));
  1414. $zipFile->close();
  1415. }
  1416. public function testUnknownCompressionMethod()
  1417. {
  1418. $zipFile = new ZipFile();
  1419. $zipFile->addFromString('file', 'content', ZipEntry::UNKNOWN);
  1420. $zipFile->addFromString('file2', base64_encode(CryptoUtil::randomBytes(512)), ZipEntry::UNKNOWN);
  1421. self::assertEquals($zipFile->getEntryInfo('file')->getMethodName(), 'Unknown');
  1422. self::assertEquals($zipFile->getEntryInfo('file2')->getMethodName(), 'Unknown');
  1423. $zipFile->saveAsFile($this->outputFilename);
  1424. $zipFile->close();
  1425. $zipFile->openFile($this->outputFilename);
  1426. self::assertEquals($zipFile->getEntryInfo('file')->getMethodName(), 'No compression');
  1427. self::assertEquals($zipFile->getEntryInfo('file2')->getMethodName(), 'Deflate');
  1428. $zipFile->close();
  1429. }
  1430. /**
  1431. * @expectedException \PhpZip\Exception\InvalidArgumentException
  1432. * @expectedExceptionMessage DirName empty
  1433. */
  1434. public function testAddEmptyDirNullName()
  1435. {
  1436. $zipFile = new ZipFile();
  1437. $zipFile->addEmptyDir(null);
  1438. }
  1439. /**
  1440. * @expectedException \PhpZip\Exception\InvalidArgumentException
  1441. * @expectedExceptionMessage DirName empty
  1442. */
  1443. public function testAddEmptyDirEmptyName()
  1444. {
  1445. $zipFile = new ZipFile();
  1446. $zipFile->addEmptyDir("");
  1447. }
  1448. /**
  1449. * @expectedException \PhpZip\Exception\ZipNotFoundEntry
  1450. * @expectedExceptionMessage Zip entry "bad entry name" not found
  1451. */
  1452. public function testNotFoundEntry()
  1453. {
  1454. $zipFile = new ZipFile();
  1455. $zipFile['bad entry name'];
  1456. }
  1457. /**
  1458. * Test rewrite input file.
  1459. */
  1460. public function testRewriteFile()
  1461. {
  1462. $zipFile = new ZipFile();
  1463. $zipFile['file'] = 'content';
  1464. $zipFile['file2'] = 'content2';
  1465. self::assertEquals(count($zipFile), 2);
  1466. $zipFile
  1467. ->saveAsFile($this->outputFilename)
  1468. ->close();
  1469. $md5file = md5_file($this->outputFilename);
  1470. $zipFile->openFile($this->outputFilename);
  1471. self::assertEquals(count($zipFile), 2);
  1472. self::assertTrue(isset($zipFile['file']));
  1473. self::assertTrue(isset($zipFile['file2']));
  1474. $zipFile['file3'] = 'content3';
  1475. self::assertEquals(count($zipFile), 3);
  1476. $zipFile = $zipFile->rewrite();
  1477. self::assertEquals(count($zipFile), 3);
  1478. self::assertTrue(isset($zipFile['file']));
  1479. self::assertTrue(isset($zipFile['file2']));
  1480. self::assertTrue(isset($zipFile['file3']));
  1481. $zipFile->close();
  1482. self::assertNotEquals(md5_file($this->outputFilename), $md5file);
  1483. }
  1484. /**
  1485. * Test rewrite for string.
  1486. */
  1487. public function testRewriteString()
  1488. {
  1489. $zipFile = new ZipFile();
  1490. $zipFile['file'] = 'content';
  1491. $zipFile['file2'] = 'content2';
  1492. $zipFile->saveAsFile($this->outputFilename);
  1493. $zipFile->close();
  1494. $zipFile->openFromString(file_get_contents($this->outputFilename));
  1495. self::assertEquals(count($zipFile), 2);
  1496. self::assertTrue(isset($zipFile['file']));
  1497. self::assertTrue(isset($zipFile['file2']));
  1498. $zipFile['file3'] = 'content3';
  1499. $zipFile = $zipFile->rewrite();
  1500. self::assertEquals(count($zipFile), 3);
  1501. self::assertTrue(isset($zipFile['file']));
  1502. self::assertTrue(isset($zipFile['file2']));
  1503. self::assertTrue(isset($zipFile['file3']));
  1504. $zipFile->close();
  1505. }
  1506. /**
  1507. * @expectedException \PhpZip\Exception\ZipException
  1508. * @expectedExceptionMessage input stream is null
  1509. */
  1510. public function testRewriteNullStream()
  1511. {
  1512. $zipFile = new ZipFile();
  1513. $zipFile->rewrite();
  1514. }
  1515. public function testFilename0()
  1516. {
  1517. $zipFile = new ZipFile();
  1518. $zipFile[0] = 0;
  1519. self::assertTrue(isset($zipFile[0]));
  1520. self::assertTrue(isset($zipFile['0']));
  1521. self::assertCount(1, $zipFile);
  1522. $zipFile
  1523. ->saveAsFile($this->outputFilename)
  1524. ->close();
  1525. self::assertCorrectZipArchive($this->outputFilename);
  1526. $zipFile->openFile($this->outputFilename);
  1527. self::assertTrue(isset($zipFile[0]));
  1528. self::assertTrue(isset($zipFile['0']));
  1529. self::assertEquals($zipFile['0'], '0');
  1530. self::assertCount(1, $zipFile);
  1531. $zipFile->close();
  1532. self::assertTrue(unlink($this->outputFilename));
  1533. $zipFile = new ZipFile();
  1534. $zipFile->addFromString(0, 0);
  1535. self::assertTrue(isset($zipFile[0]));
  1536. self::assertTrue(isset($zipFile['0']));
  1537. self::assertCount(1, $zipFile);
  1538. $zipFile
  1539. ->saveAsFile($this->outputFilename)
  1540. ->close();
  1541. self::assertCorrectZipArchive($this->outputFilename);
  1542. }
  1543. public function testPsrResponse()
  1544. {
  1545. $zipFile = new ZipFile();
  1546. for ($i = 0; $i < 10; $i++) {
  1547. $zipFile[$i] = $i;
  1548. }
  1549. $filename = 'file.jar';
  1550. $response = $this->getMock(ResponseInterface::class);
  1551. $response = $zipFile->outputAsResponse($response, $filename);
  1552. $this->assertInstanceOf(ResponseInterface::class, $response);
  1553. }
  1554. public function testCompressionLevel()
  1555. {
  1556. $zipFile = new ZipFile();
  1557. $zipFile
  1558. ->addFromString('file', 'content', ZipFileInterface::METHOD_DEFLATED)
  1559. ->setCompressionLevelEntry('file', ZipFileInterface::LEVEL_BEST_COMPRESSION)
  1560. ->addFromString('file2', 'content', ZipFileInterface::METHOD_DEFLATED)
  1561. ->setCompressionLevelEntry('file2', ZipFileInterface::LEVEL_FAST)
  1562. ->addFromString('file3', 'content', ZipFileInterface::METHOD_DEFLATED)
  1563. ->setCompressionLevelEntry('file3', ZipFileInterface::LEVEL_SUPER_FAST)
  1564. ->addFromString('file4', 'content', ZipFileInterface::METHOD_DEFLATED)
  1565. ->setCompressionLevelEntry('file4', ZipFileInterface::LEVEL_DEFAULT_COMPRESSION)
  1566. ->saveAsFile($this->outputFilename)
  1567. ->close();
  1568. self::assertCorrectZipArchive($this->outputFilename);
  1569. $zipFile->openFile($this->outputFilename);
  1570. self::assertEquals($zipFile->getEntryInfo('file')
  1571. ->getCompressionLevel(), ZipFileInterface::LEVEL_BEST_COMPRESSION);
  1572. self::assertEquals($zipFile->getEntryInfo('file2')
  1573. ->getCompressionLevel(), ZipFileInterface::LEVEL_FAST);
  1574. self::assertEquals($zipFile->getEntryInfo('file3')
  1575. ->getCompressionLevel(), ZipFileInterface::LEVEL_SUPER_FAST);
  1576. self::assertEquals($zipFile->getEntryInfo('file4')
  1577. ->getCompressionLevel(), ZipFileInterface::LEVEL_DEFAULT_COMPRESSION);
  1578. $zipFile->close();
  1579. }
  1580. /**
  1581. * @expectedException \PhpZip\Exception\InvalidArgumentException
  1582. * @expectedExceptionMessage Invalid compression level
  1583. */
  1584. public function testInvalidCompressionLevel()
  1585. {
  1586. $zipFile = new ZipFile();
  1587. $zipFile->addFromString('file', 'content');
  1588. $zipFile->setCompressionLevel(15);
  1589. }
  1590. /**
  1591. * @expectedException \PhpZip\Exception\InvalidArgumentException
  1592. * @expectedExceptionMessage Invalid compression level
  1593. */
  1594. public function testInvalidCompressionLevelEntry()
  1595. {
  1596. $zipFile = new ZipFile();
  1597. $zipFile->addFromString('file', 'content');
  1598. $zipFile->setCompressionLevelEntry('file', 15);
  1599. }
  1600. public function testCompressionGlobal()
  1601. {
  1602. $zipFile = new ZipFile();
  1603. for ($i = 0; $i < 10; $i++) {
  1604. $zipFile->addFromString('file' . $i, 'content', ZipFileInterface::METHOD_DEFLATED);
  1605. }
  1606. $zipFile
  1607. ->setCompressionLevel(ZipFileInterface::LEVEL_BEST_SPEED)
  1608. ->saveAsFile($this->outputFilename)
  1609. ->close();
  1610. self::assertCorrectZipArchive($this->outputFilename);
  1611. $zipFile->openFile($this->outputFilename);
  1612. $infoList = $zipFile->getAllInfo();
  1613. array_walk($infoList, function (ZipInfo $zipInfo) {
  1614. self::assertEquals($zipInfo->getCompressionLevel(), ZipFileInterface::LEVEL_BEST_SPEED);
  1615. });
  1616. $zipFile->close();
  1617. }
  1618. public function testCompressionMethodEntry()
  1619. {
  1620. $zipFile = new ZipFile();
  1621. $zipFile->addFromString('file', 'content', ZipFileInterface::METHOD_STORED);
  1622. $zipFile->saveAsFile($this->outputFilename);
  1623. $zipFile->close();
  1624. $zipFile->openFile($this->outputFilename);
  1625. self::assertEquals($zipFile->getEntryInfo('file')->getMethodName(), 'No compression');
  1626. $zipFile->setCompressionMethodEntry('file', ZipFileInterface::METHOD_DEFLATED);
  1627. self::assertEquals($zipFile->getEntryInfo('file')->getMethodName(), 'Deflate');
  1628. $zipFile->rewrite();
  1629. self::assertEquals($zipFile->getEntryInfo('file')->getMethodName(), 'Deflate');
  1630. }
  1631. /**
  1632. * @expectedException \PhpZip\Exception\ZipUnsupportMethod
  1633. * @expectedExceptionMessage Unsupported method
  1634. */
  1635. public function testInvalidCompressionMethodEntry()
  1636. {
  1637. $zipFile = new ZipFile();
  1638. $zipFile->addFromString('file', 'content', ZipFileInterface::METHOD_STORED);
  1639. $zipFile->setCompressionMethodEntry('file', 99);
  1640. }
  1641. public function testUnchangeAll()
  1642. {
  1643. $zipFile = new ZipFile();
  1644. for ($i = 0; $i < 10; $i++) {
  1645. $zipFile[$i] = $i;
  1646. }
  1647. $zipFile->setArchiveComment('comment');
  1648. self::assertCount(10, $zipFile);
  1649. self::assertEquals($zipFile->getArchiveComment(), 'comment');
  1650. $zipFile->saveAsFile($this->outputFilename);
  1651. $zipFile->unchangeAll();
  1652. self::assertCount(0, $zipFile);
  1653. self::assertEquals($zipFile->getArchiveComment(), null);
  1654. $zipFile->close();
  1655. $zipFile->openFile($this->outputFilename);
  1656. self::assertCount(10, $zipFile);
  1657. self::assertEquals($zipFile->getArchiveComment(), 'comment');
  1658. for ($i = 10; $i < 100; $i++) {
  1659. $zipFile[$i] = $i;
  1660. }
  1661. $zipFile->setArchiveComment('comment 2');
  1662. self::assertCount(100, $zipFile);
  1663. self::assertEquals($zipFile->getArchiveComment(), 'comment 2');
  1664. $zipFile->unchangeAll();
  1665. self::assertCount(10, $zipFile);
  1666. self::assertEquals($zipFile->getArchiveComment(), 'comment');
  1667. $zipFile->close();
  1668. }
  1669. public function testUnchangeArchiveComment()
  1670. {
  1671. $zipFile = new ZipFile();
  1672. for ($i = 0; $i < 10; $i++) {
  1673. $zipFile[$i] = $i;
  1674. }
  1675. $zipFile->setArchiveComment('comment');
  1676. self::assertEquals($zipFile->getArchiveComment(), 'comment');
  1677. $zipFile->saveAsFile($this->outputFilename);
  1678. $zipFile->unchangeArchiveComment();
  1679. self::assertEquals($zipFile->getArchiveComment(), null);
  1680. $zipFile->close();
  1681. $zipFile->openFile($this->outputFilename);
  1682. self::assertEquals($zipFile->getArchiveComment(), 'comment');
  1683. $zipFile->setArchiveComment('comment 2');
  1684. self::assertEquals($zipFile->getArchiveComment(), 'comment 2');
  1685. $zipFile->unchangeArchiveComment();
  1686. self::assertEquals($zipFile->getArchiveComment(), 'comment');
  1687. $zipFile->close();
  1688. }
  1689. public function testUnchangeEntry()
  1690. {
  1691. $zipFile = new ZipFile();
  1692. $zipFile['file 1'] = 'content 1';
  1693. $zipFile['file 2'] = 'content 2';
  1694. $zipFile
  1695. ->saveAsFile($this->outputFilename)
  1696. ->close();
  1697. $zipFile->openFile($this->outputFilename);
  1698. $zipFile['file 1'] = 'modify content 1';
  1699. $zipFile->setPasswordEntry('file 1', 'password');
  1700. self::assertEquals($zipFile['file 1'], 'modify content 1');
  1701. self::assertTrue($zipFile->getEntryInfo('file 1')->isEncrypted());
  1702. self::assertEquals($zipFile['file 2'], 'content 2');
  1703. self::assertFalse($zipFile->getEntryInfo('file 2')->isEncrypted());
  1704. $zipFile->unchangeEntry('file 1');
  1705. self::assertEquals($zipFile['file 1'], 'content 1');
  1706. self::assertFalse($zipFile->getEntryInfo('file 1')->isEncrypted());
  1707. self::assertEquals($zipFile['file 2'], 'content 2');
  1708. self::assertFalse($zipFile->getEntryInfo('file 2')->isEncrypted());
  1709. $zipFile->close();
  1710. }
  1711. /**
  1712. * Test support ZIP64 ext (slow test - normal).
  1713. * Create > 65535 files in archive and open and extract to /dev/null.
  1714. */
  1715. public function testCreateAndOpenZip64Ext()
  1716. {
  1717. $countFiles = 0xffff + 1;
  1718. $zipFile = new ZipFile();
  1719. for ($i = 0; $i < $countFiles; $i++) {
  1720. $zipFile[$i . '.txt'] = $i;
  1721. }
  1722. $zipFile->saveAsFile($this->outputFilename);
  1723. $zipFile->close();
  1724. self::assertCorrectZipArchive($this->outputFilename);
  1725. $zipFile->openFile($this->outputFilename);
  1726. self::assertEquals($zipFile->count(), $countFiles);
  1727. $i = 0;
  1728. foreach ($zipFile as $entry => $content) {
  1729. self::assertEquals($entry, $i . '.txt');
  1730. self::assertEquals($content, $i);
  1731. $i++;
  1732. }
  1733. $zipFile->close();
  1734. }
  1735. }