Php ZipArchive add's extra folder

327 views Asked by At

zipping some directory on the server I receive extra folder inside zip-archive under Windows and Linux.

enter image description here

Extra folder "3b84" is the ending of using md5(integer) function to set filename inside getExportPaths() method. If I try to make filename shorter - it makes me a zip archive where all files placed in one directory without their subdirectories like "CSS", "fonts" etc.

And one important thing why I'm using md5() - I need to paste into one directory a lot of zip archives. So their name should be unique.

How to fix this and remove such extra folder with a name like "3b84"?

public function actionExportdocument($id)
{
    $model = Order::findOne(['id' => $id, 'user_id' => Yii::$app->user->getId()]);

    if (!$model) {
        throw new BadRequestHttpException('Export not found.');
    }


    $paths = Order::getExportPaths($model->id, $model->design->path);
    $prepareFiles = Order::prepareFiles($paths, $model);

    $zip = new ZipArchive();
    $zip->open($paths['exportRoot'] . DIRECTORY_SEPARATOR . $paths['exportFile'],
        ZipArchive::CREATE | ZipArchive::OVERWRITE);

    $files = new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator($paths['exportPath']),
        RecursiveIteratorIterator::LEAVES_ONLY
    );

    foreach ($files as $name => $file)
    {
        // Skip directories (they would be added automatically)
        if (!$file->isDir())
        {
            $filePath = $file->getRealPath();
            $relativePath = substr($filePath, strlen($paths['designPath']) + 1);
            $zip->addFile($filePath, $relativePath);
        }
    }
    $zip->close();

    FileHelper::sendFile($paths['exportRoot'] . DIRECTORY_SEPARATOR . $paths['exportFile'], 'script.zip');
}

Order class contains:

public static function getExportPaths($modelId, $designPath)
{
    $paths['orderIdHash'] = md5($modelId);

    $paths['designPath'] = \Yii::getAlias('@app') . DIRECTORY_SEPARATOR . 'designs' . DIRECTORY_SEPARATOR . $designPath;
    $paths['exportRoot'] = \Yii::getAlias('@webroot') . DIRECTORY_SEPARATOR . 'export-document';
    $paths['exportPath'] =  $paths['exportRoot'] . DIRECTORY_SEPARATOR . $paths['orderIdHash'];
    $paths['exportFile'] = $paths['orderIdHash'] . '.zip';

    return $paths;
}

public static function prepareFiles($paths, $model)
{
    $exportDir = \Yii::getAlias('@webroot') . DIRECTORY_SEPARATOR . 'export-document';
    if (!is_dir($exportDir)) {
        mkdir($exportDir);
    }

    FileHelper::deleteDirectory($paths['exportPath']);
    FileHelper::copyRecursive($paths['designPath'], $paths['exportPath']);

    $content = '';
    foreach ($model->orderTemplates as $template) {
        $content .= $template->value;
    }

    $str = file_get_contents($paths['exportPath'] . DIRECTORY_SEPARATOR . 'index.html');
    $str = str_replace("{{CONTENT}}", $content, $str);
    file_put_contents($paths['exportPath'] . DIRECTORY_SEPARATOR . 'index.html', $str);

}
2

There are 2 answers

2
IsThisJavascript On

If I've read your question correctly; you wish to remove folders like /3b84/ from being generated.
Look inside your Order class:

public static function getExportPaths($modelId, $designPath)
{
    $paths['orderIdHash'] = md5($modelId);

    $paths['designPath'] = \Yii::getAlias('@app') . DIRECTORY_SEPARATOR . 'designs' . DIRECTORY_SEPARATOR . $designPath;
    $paths['exportRoot'] = \Yii::getAlias('@webroot') . DIRECTORY_SEPARATOR . 'export-document';
    $paths['exportPath'] =  $paths['exportRoot'] . DIRECTORY_SEPARATOR . $paths['orderIdHash'];
    $paths['exportFile'] = $paths['orderIdHash'] . '.zip';

    return $paths;
}

See $paths['exportPath'] = $paths['exportRoot'] . DIRECTORY_SEPARATOR . $paths['orderIdHash']; ?
Remove that and you your new path will no longer have folders like /3b84/.

0
white-imp On

The problem was that I've specified wrong $relativePath.

This string was incorrect

$relativePath = substr($filePath, strlen($paths['designPath']) + 1);  

And instead of it

$relativePath = substr($filePath, strlen($paths['exportPath']) + 1);