lgt
lgt

Reputation: 1034

PHP zip function

I'm trying to build a directory tree with specific files from an array and push it to download. This part is working fine.

The problem is when I try to fill the specific files with content.

After the download is finished the files are empty.

However the switch case statement is executed and all the methods are working.

The problem I think is around my zip function, but I don't really know what should I search for (or maybe the code design is not the best one).

<?php
include_once 'class.file.php';

class CreateComponent{



    function __construct(){

        if (isset($_POST['name'])){

        $this->createDirectoryTree($_POST['name']);

        }

        else{

            echo '<h1>error!</h1>';

        }

    }   

    function createDirectoryTree($component_name){

        $component_name="com_".$component_name;

        $this->create_zip($component_name);

    }

    function create_zip($component) {


        $jcomp=str_replace("com_", "", $component);

        $dirs= array(
                $jcomp.'.xml',
                'site/'.$jcomp.'.php',
                'site/views/index.html',
                'site/views/to_change/index.html',
                'site/views/to_change/tmpl/index.html',
                'site/views/to_change/tmpl/default.xml',
                'site/views/to_change/tmpl/default.php',
                'site/models/index.html',
                'site/controllers/index.html',
                'site/tables/index.html',
                'site/index.html',
                'admin/index.html',
                'admin/views/index.html',
                'admin/models/index.html',
                'admin/controllers/index.html',
                'admin/sql/updates/index.html',
                'admin/sql/updates/mysql/0_1.sql'
        );

        $file = tempnam("tmp", "zip");

        $zip = new ZipArchive();

        foreach ($dirs as $dir){
            $zip->open($file, ZIPARCHIVE::CREATE);
            $zip->addEmptyDir($dir);


        switch ($dir){

            case (substr( $dir, strrpos( $dir, '/' )+1 ) == "index.html"):

            $zip->addFromString($dir, '<html><body bgcolor="#FFFFFF"></body></html>');
            break;

            case "site/$jcomp.php":
            $main_php= new File();
//          echo $main_php->main_controller($jcomp);
            $zip->addFromString($dir,$main_php->main_controller($jcomp));

            $zip->addFromString($dir, '');
            break;

            case "$jcomp.xml":
            $main_php= new File();
            $zip->addFromString($dir,$main_php->main_xml($jcomp));

            break;


}


        $zip->addFromString($dir, '');


        }
        $zip->close();



        // Stream the file to the client
        header('Content-Type: application/zip');
        header('Content-Length: ' . filesize($file));
        header('Content-Disposition: attachment; filename= "'.$component.'.zip"');
        readfile($file);
        unlink($file);
    }



}

$component= new CreateComponent();

Upvotes: 1

Views: 497

Answers (1)

Eineki
Eineki

Reputation: 14909

At a first glance I would change the following lines

    $zip = new ZipArchive();

    foreach ($dirs as $dir){
        $zip->open($file, ZIPARCHIVE::CREATE);
        $zip->addEmptyDir($dir);

to

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

    foreach ($dirs as $dir){
        $zip->addEmptyDir($dir);

as you are opening the file everytime you add a directory and it seems wrong to me.

On the other hand I would set a component name policy and check for it in the constructor in order to prevent input exploitation.

I don't know, maybe a good name policy would be - just alpha chars, numbers and dashes are allowed into a module name -

Upvotes: 1

Related Questions