protected function zipPHP($sourceDirectory, $zipFile, array $options)
    {
        if (!class_exists('ZipArchive')) {
            throw new Exception('Unable to zip files using ZipArchive. Please ensure the Zip extension is installed.');
        }
        $zip = new ZipArchive();
        try {
            $flags = ZipArchive::CREATE;
            if (!$options['skipCheck']) {
                $flags |= ZipArchive::CHECKCONS;
            }
            $zipErr = @$zip->open($zipFile, $flags);
            if ($zipErr !== true) {
                throw new Exception($this->describeZipArchiveError($zip, $zipErr));
            }
            $skipPathLength = strlen(rtrim(str_replace(DIRECTORY_SEPARATOR, '/', $sourceDirectory), '/')) + 1;
            $contents = new \RecursiveIteratorIterator(
                new \RecursiveDirectoryIterator($sourceDirectory),
                \RecursiveIteratorIterator::SELF_FIRST
            );
            foreach ($contents as $item) {
                switch ($item->getFilename()) {
                    case '.':
                    case '..':
                        break;
                    default:
                        $itemFullPath = $item->getRealPath();
                        $itemRelPath = substr(str_replace(DIRECTORY_SEPARATOR, '/', $itemFullPath), $skipPathLength);
                        if (
                            $options['includeDotFiles']
                            ||
                            (
                                strpos($itemRelPath, '.') !== 0
                                &&
                                strpos($itemRelPath, '/.') === false
                            )
                        ) {
                            if ($item->isDir()) {
                                $added = @$zip->addEmptyDir($itemRelPath);
                            } else {
                                $added = @$zip->addFile($itemFullPath, $itemRelPath);
                            }
                            if ($added !== true) {
                                throw new Exception($this->describeZipArchiveError($zip, ZipArchive::ER_OK));
                            }
                        }
                        break;
                }
            }
            if (@$zip->close() !== true) {
                throw new Exception($this->describeZipArchiveError($zip, ZipArchive::ER_OK));
            }
            $zip = null;
        } catch (Exception $x) {
            if ($zip !== null) {
                try {
                    @$zip->close();
                } catch (\Exception $foo) {
                }
                $zip = null;
            }
            @$this->getFilesystem()->delete([$zipFile]);
            throw $x;
        }
    }