protected function unzip()

in lib/php/libsdk/SDK/FileOps.php [169:220]


	protected function unzip(string $zip_fn, string $dest_fn, string $dest_dn = NULL) : void
	{/*{{{*/
		$zip = new \ZipArchive;

		$res = $zip->open($zip_fn);
		if (true !== $res) {
			throw new Exception("Failed to open '$zip_fn'.");
		}

		$res = $zip->extractTo($dest_fn);
		if (true !== $res) {
			$zip->close();
			throw new Exception("Failed to unzip '$zip_fn'.");
		}

		/* Not robust, useful for zips containing one dir sibling only in the root. */
		if ($dest_dn) {
			$stat = $zip->statIndex(0);
			if (false === $stat) {
				$zip->close();
				throw new Exception("Failed to stat first index in '$zip_fn'.");
			}

			$zip->close();

			/* Index of zero might be not the zipped folder, unusual but true. */
			/*$name = $stat["name"];
			if ("/" != substr($name, -1)) {
				throw new Exception("'$name' is not a directory.");
			}
			$name = substr($name, 0, -1);*/

			$name = rtrim($stat["name"], "/");
			while (strstr($name, '/') !== false) {
				$name = dirname($name);
			}

			$old_dir = $dest_fn . DIRECTORY_SEPARATOR . $name;
			$new_dir = $dest_fn . DIRECTORY_SEPARATOR . $dest_dn;
			if (file_exists($new_dir)) {
				if (!$this->rm($new_dir)) {
					throw new Exception("Failed to remove '$new_dir'.");
				}
			}
			/* if (!$this->mv($old_dir, $new_dir)) { */
			if (!rename($old_dir, $new_dir)) {
				throw new Exception("Failed to rename '$old_dir' to '$new_dir'.");
			}
		} else {
			$zip->close();
		}
	}/*}}}*/