Add item to zip archive

@param string $file File to add (realpath)
@param bool $flatroot (optional) If true, source directory will be not included
@param string $base (optional) Base to record in zip file
@return void
@throws ZipException
347817
private function addItem(
        string $file,
        bool $flatroot = false,
        int $compression = self::CM_DEFAULT,
        int $encryption = self::EM_NONE,
        ?string $base = null
    ): void {

        $file = is_null($this->getPath()) ? $file : $this->getPath()."/$file";
        $real_file = str_replace('\\', '/', realpath($file));
        $real_name = basename($real_file);

        if (
            $base !== null &&
            (
                (
                    $real_name[0] == "." &&
                    in_array($this->getSkipMode(), ["HIDDEN", "ALL"])
                ) ||
                (
                    $real_name[0] == "." &&
                    @$real_name[1] == "_" &&
                    in_array($this->getSkipMode(), ["COMODOJO", "ALL"])
                )
            )
        ) {
            return;
        }

        if ( is_dir($real_file) ) {
            $this->addDirectoryItem($real_file, $real_name, $compression, $encryption, $base, $flatroot);
        } else {
            $this->addFileItem($real_file, $real_name, $compression, $encryption, $base);
        }

    }
1314514
@Override
    public void add(File file, String baseURI, RDFFormat dataFormat, Resource... contexts) throws IOException, RDFParseException, RepositoryException {
        if(notNull(baseURI)) {
            getClient().sendAdd(file, baseURI, dataFormat, contexts);
        }else{
            getClient().sendAdd(file, file.toURI().toString(), dataFormat, contexts);
        }
    }
288722
public function unzip($file, $path)
    {
        if (ends_with($file, '.zip')) {
            $this->message("Unzipping to {$file}");

            $this->unzipFile($file, $path);
        }
    }
1157680
private static void addFile(final File file, final File dirToZip, final ZipOutputStream zos)
		throws IOException
	{
		final String absolutePath = file.getAbsolutePath();
		final int index = absolutePath.indexOf(dirToZip.getName());
		final String zipEntryName = absolutePath.substring(index, absolutePath.length());
		final byte[] b = new byte[(int)file.length()];
		final ZipEntry cpZipEntry = new ZipEntry(zipEntryName);
		zos.putNextEntry(cpZipEntry);
		zos.write(b, 0, (int)file.length());
		zos.closeEntry();
	}
189295
public function add($file, $entry_name = null)
    {
        $result = $this->tar->addModify($file, '', dirname($file));
        if ($result === false) {
            throw new ArchiveException('Error adding file ' . $file);
        }

        return $this;
    }
1278787
private void zipDirectory(String zipFile, String dirToZip) {
    File directory = new File(dirToZip);
    try (ZipOutputStream stream = new ZipOutputStream(new FileOutputStream(zipFile))) {
      addDirectoryToZip(directory, directory, stream);
    } catch (Exception e) {
      throw new PlatformManagerException("Failed to zip module", e);
    }
  }
690207
public static function create($file)
    {
        // Verify ZipArchive is installed
        $zipArchive = class_exists('ZipArchive');

        try {
            return self::makeZipArchiver($file, ! $zipArchive, true);
        } catch ( Exception $e ) {
            return self::makeZipArchiver($file, $zipArchive, true);
        }
    }
347688
public function set($path, $create = false)
    {
        $zip = $this->zip;
        $flag = $create ? $zip::CREATE : null;

        if ($this->zip->open($path, $flag) !== true) {
            throw new RuntimeException("Failed to open ZIP file $path");
        }

        return $this;
    }
585092
public function addDirectory($source) {
        $source = str_replace('\\', '/', realpath($source));

        if (is_dir($source) === true) {
            $files = new RecursiveIteratorIterator(
                new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);

            foreach ($files as $file) {
                $file = str_replace('\\', '/', $file);

                // Ignore "." and ".." folders
                if( in_array(substr($file, strrpos($file, '/')+1), array('.', '..')) )
                    continue;

                if (!is_link($file)) {
                    $file = realpath($file);
                }

                if (!is_link($file) && is_dir($file)) {
                    $this->addEmptyDir(str_replace($source . '/', '', $file . '/'));
                } else if (is_link($file)) {
                    // @fixme This actually does not work. It will create a file in the zip, but it
                    // won't be a link pointing somewhere.
                    // I have not found a way to add a working symlink to a zip archive.
                    $this->addFile($file, str_replace($source . '/', '', $file));
                } else if (is_file($file)) {
                    $this->addFromString(str_replace($source . '/', '', $file),
                        file_get_contents($file));
                }
            }
        } else if (is_file($source) === true) {
            $this->addFromString(basename($source), file_get_contents($source));
        }
    }
462471
public function setRootAndPath(Document $root, $path)
    {
        $this->getArchive()->set('root_and_path', array('root' => $root, 'path' => $path));

        foreach ($this->getAdd() as $key => $document) {
            $document->setRootAndPath($root, $path.'._add'.$key);
        }
    }
424962
public function create($file = '')
    {
        $this->file   = $file;
        $this->memory = '';
        $this->fh     = 0;

        if ($this->file) {
            // determine compression
            if ($this->comptype == Archive::COMPRESS_AUTO) {
                $this->setCompression($this->complevel, $this->filetype($file));
            }

            if ($this->comptype === Archive::COMPRESS_GZIP) {
                $this->fh = @gzopen($this->file, 'wb'.$this->complevel);
            } elseif ($this->comptype === Archive::COMPRESS_BZIP) {
                $this->fh = @bzopen($this->file, 'w');
            } else {
                $this->fh = @fopen($this->file, 'wb');
            }

            if (!$this->fh) {
                throw new ArchiveIOException('Could not open file for writing: '.$this->file);
            }
        }
        $this->writeaccess = true;
        $this->closed      = false;
    }
280039
protected function addResourceFile(string $file): void
    {
        if (!is_file($file)) {
            throw new \InvalidArgumentException("$file is not a file");
        }
        
        $contents = file_get_contents($file);
        
        if ($contents === false) {
            throw new \RuntimeException("Error reading file at $file.");
        }
        
        $this->addResourceString($contents);
    }
221395
public function add_stored_file($file) {
        if (is_numeric($file)) {
            $this->files[$file] = $file;
        } else {
            $this->files[$file->get_id()] = $file;
        }
    }
670541
public function addFile(string $file, string $locale = null): self
	{
		$collection = $this->getCollection($this->getType($file), $locale);
		if ($this->isRemoteFile($file)) {
			$collection->addRemoteFile($file);
		} else {
			$collection->addFile($file);
		}
		return $this;
	}
87223
public function addTrace($file)
    {
        // If the file does not contain the trace, add it.
        if (strpos(File::get($file), $this->realPath) === false && $this->debug == true) {
            File::prepend($file, $this->realPath);
            File::append($file, '</span>');
        }
    }
1207781
public function import( $file, $basename = null )
    {
        static $validSchema     = 'vendor/gridguyz/core/module/Core/public/styles/schemas/paragraph/1.0.xsd';
        static $validSystemIds  = array(
            'http://gridguyz.com/styles/schemas/paragraph/1.0.dtd',
            'public/styles/schemas/paragraph/1.0.dtd',
            './public/styles/schemas/paragraph/1.0.dtd',
            'vendor/gridguyz/core/module/Core/public/styles/schemas/paragraph/1.0.dtd',
            './vendor/gridguyz/core/module/Core/public/styles/schemas/paragraph/1.0.dtd',
        );

        if ( $file instanceof ZipArchive )
        {
            $zip = $file;

            if ( $basename )
            {
                $file = $basename;
            }
            else
            {
                $basename = $file = '$object.zip';
            }
        }
        else
        {
            if ( ! $basename )
            {
                $basename = basename( $file );
            }

            if ( ! is_file( $file ) )
            {
                return new ImportResult(
                    ImportResult::FILE_NOT_EXISTS,
                    sprintf(
                        '"%s" is not a file',
                        $basename
                    )
                );
            }

            $zip    = new ZipArchive();
            $open   = $zip->open( $file, ZipArchive::CHECKCONS );

            if ( $open !== true )
            {
                return new ImportResult(
                    ImportResult::FILE_NOT_ZIP,
                    sprintf(
                        '"%s" cannot be opened as a zip file (error #%d)',
                        $basename,
                        $open
                    )
                );
            }
        }

        $stats = $zip->statName( 'paragraph.xml', ZipArchive::FL_NOCASE );

        if ( empty( $stats ) ||
             empty( $stats['size'] ) ||
             ! isset( $stats['index'] ) )
        {
            return new ImportResult(
                ImportResult::STRUCTURE_XML_NOT_FOUND,
                sprintf(
                    '"paragraph.xml" is not found in "%s"',
                    $file
                )
            );
        }

        $document = new DOMDocument();
        $document->loadXML( $zip->getFromIndex( $stats['index'] ) );
        $document->documentURI  = 'paragraph.xml';
        $document->normalizeDocument();
        ErrorHandler::start();

        if ( $document->doctype )
        {
            $doctype = $document->doctype;

            if ( static::GPML_ROOT != strtolower( $doctype->name ) )
            {
                ErrorHandler::stop();

                return new ImportResult(
                    ImportResult::STRUCTURE_XML_DOCTYPE_MISMATCH,
                    sprintf(
                        'DOCTYPE "%s" in "%s#paragraph.xml" does not match "%s"',
                        $doctype->name,
                        $basename,
                        static::GPML_ROOT
                    )
                );
            }

            if ( ! in_array( $doctype->systemId, $validSystemIds ) )
            {
                ErrorHandler::stop();

                return new ImportResult(
                    ImportResult::STRUCTURE_XML_DOCTYPE_MISMATCH,
                    sprintf(
                        'SYSTEM ID "%s" in "%s#paragraph.xml"\'s ' .
                            'DOCTYPE does not match one of "%s"',
                        $doctype->systemId,
                        $basename,
                        implode( '", "', $validSystemIds )
                    )
                );
            }

            if ( ! $document->validate() )
            {
                $error = ErrorHandler::stop();

                return new ImportResult(
                    ImportResult::STRUCTURE_XML_NOT_VALID,
                    $error ? $error->getMessage() : null
                );
            }
        }

        if ( ! $document->schemaValidate( realpath( $validSchema ) ) )
        {
            $error = ErrorHandler::stop();

            return new ImportResult(
                ImportResult::STRUCTURE_XML_NOT_VALID,
                $error ? $error->getMessage() : null
            );
        }

        $rootParagraphId    = null;
        $domains            = array();
        $paragraphIdMap     = array();
        $gpml               = $document->documentElement;
        $version            = $gpml->getAttribute( 'version' );
        $dbSchema           = $gpml->getAttribute( 'db-schema' );

        if ( version_compare( $version, '1.0', '<' ) )
        {
            ErrorHandler::stop();

            return new ImportResult(
                ImportResult::STRUCTURE_XML_UNKNOWN_VERSION,
                sprintf(
                    'unknown version "%s" in "%s#paragraph.xml"',
                    $version,
                    $basename
                )
            );
        }

        foreach ( $gpml->childNodes as $child )
        {
            if ( $child instanceof DOMElement )
            {
                switch ( $child->tagName )
                {
                    case 'domain':
                        $domains[] = trim( $child->textContent );
                        break;

                    case 'paragraph':
                        $type           = $child->getAttribute( 'type' );
                        $permissions    = $this->getPermissionsModel();

                        if ( ! $permissions->isAllowed( 'paragraph.' . $type, 'create' ) )
                        {
                            return new ImportResult(
                                ImportResult::STRUCTURE_TYPE_NOT_ALLOWED,
                                sprintf(
                                    'not allowed to create paragraph ' .
                                    '(type: "%s") from "%s#paragraph.xml"',
                                    $type,
                                    $basename
                                )
                            );
                        }

                        $rootParagraphId = $this->importRootParagraph(
                            $child,
                            $zip,
                            $paragraphIdMap,
                            $domains,
                            $dbSchema
                        );
                        break;

                    case 'customize-rule':
                        $this->importCustomizeRule(
                            $rootParagraphId,
                            $child,
                            $zip,
                            $paragraphIdMap,
                            $domains,
                            $dbSchema
                        );
                        break;

                    case 'customize-extra':
                        $this->importCustomizeExtra(
                            $rootParagraphId,
                            trim( $child->textContent )
                        );
                        break;
                }
            }
        }

        $error = ErrorHandler::stop();

        if ( $error )
        {
            return new ImportResult(
                ImportResult::UNKNOWN_ERROR,
                $error->getMessage()
            );
        }

        return new ImportResult(
            ImportResult::SUCCESS,
            $rootParagraphId
        );
    }
1346163
public function addTreeToZip($zip, $path)
    {
        $path = rtrim($path, '/');
        if ($this->folderExists('', $path)) {
            $files = $this->adapter->listContents($path);
            if (empty($files)) {
                $newPath = str_replace(DIRECTORY_SEPARATOR, '/', $path);
                if (!$zip->addEmptyDir($newPath)) {
                    throw new \Exception("Can not include folder '$newPath' in zip file.");
                }

                return;
            }
            foreach ($files as $file) {
                if ($file['type'] === 'dir') {
                    static::addTreeToZip($zip, $file['path']);
                } elseif ($file['type'] === 'file') {
                    $newPath = str_replace(DIRECTORY_SEPARATOR, '/', $file['path']);
                    $fileObj = $this->adapter->read($newPath);
                    if (!empty($fileObj) && isset($fileObj['contents'])) {
                        if (!$zip->addFromString($file['path'], $fileObj['contents'])) {
                            throw new \Exception("Can not include file '$newPath' in zip file.");
                        }
                    } else {
                        throw new InternalServerErrorException("Could not read file '" . $file . "'");
                    }
                }
            }
        }
    }