1. Summary
  2. Files
  3. Support
  4. Report Spam
  5. Create account
  6. Log in

root/stkaddons/trunk/include/parseUpload.php @ 9871

Revision 9871, 24.0 KB (checked in by stephenjust, 20 months ago)

[stkaddons] Handle upload errors in a more graceful manner.

Line 
1<?php
2/**
3 * copyright 2011 Stephen Just <stephenjust@users.sf.net>
4 *
5 * This file is part of stkaddons
6 *
7 * stkaddons is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * stkaddons is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with stkaddons.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21function parseUpload($file,$revision = false)
22{
23    if (!is_array($file))
24        throw new UploadException(htmlspecialchars(_('Failed to upload your file.')));
25
26    // Check for file upload errors
27    $upload_error = file_upload_error($file);
28    if ($upload_error !== false)
29        throw new UploadException($upload_error);
30
31    // This won't be set when uploading addons/revisions
32    if (!isset($_POST['upload-type'])) $_POST['upload-type'] = NULL;
33   
34    // Check file-extension for uploaded file
35    $fileext = check_extension($file['name'], $_POST['upload-type']);
36
37    // Generate a unique file name for the uploaded file
38    $fileid = uniqid(true);
39   
40    // Set upload directory
41    if ($_POST['upload-type'] == 'image')
42        $file_dir = 'images/';
43    else
44        $file_dir = NULL;
45   
46    // Make sure file at this path doesn't already exist
47    while (file_exists(UP_LOCATION.$file_dir.$fileid.'.'.$fileext))
48        $fileid = uniqid();
49   
50    // Handle image uploads
51    if ($_POST['upload-type'] == 'image')
52    {
53        if (!move_uploaded_file($file['tmp_name'],UP_LOCATION.'images/'.$fileid.'.'.$fileext))
54            throw new UploadException(htmlspecialchars(_('Failed to move uploaded file.')));
55       
56        // Add database record for image
57        $addon_id = Addon::cleanId($_GET['name']);
58        $addon_type = mysql_real_escape_string($_GET['type']);
59        $newImageQuery = 'CALL `'.DB_PREFIX.'create_file_record` '.
60            "('$addon_id','$addon_type','image','images/$fileid.$fileext',@a)";
61        $newImageHandle = sql_query($newImageQuery);
62        if (!$newImageHandle)
63        {
64            unlink(UP_LOCATION.'images/'.$fileid.'.'.$fileext);
65            throw new UploadException(htmlspecialchars(_('Failed to associate image file with addon.')));
66        }
67       
68        echo htmlspecialchars(_('Successfully uploaded image.')).'<br />';
69        echo '<span style="font-size: large"><a href="addons.php?type='.$_GET['type'].'&amp;name='.$_GET['name'].'">'.htmlspecialchars(_('Continue.')).'</a></span><br />';
70        return true;
71    }
72   
73    // Move the archive to a working directory
74    mkdir(UP_LOCATION.'temp/'.$fileid);
75    if (!move_uploaded_file($file['tmp_name'],UP_LOCATION.'temp/'.$fileid.'/'.$fileid.'.'.$fileext))
76        throw new UploadException(htmlspecialchars(_('Failed to move uploaded file.')));
77
78    // Extract archive
79    if (!extract_archive(UP_LOCATION.'temp/'.$fileid.'/'.$fileid.'.'.$fileext,
80            UP_LOCATION.'temp/'.$fileid.'/',
81            $fileext))
82    {
83        rmdir_recursive(UP_LOCATION.'temp/'.$fileid);
84    }
85
86    // Find XML file
87    if ($_POST['upload-type'] != 'source')
88    {
89        $xml_file = find_xml(UP_LOCATION.'temp/'.$fileid);
90        $xml_dir = dirname($xml_file);
91        if (!$xml_file) {
92            rmdir_recursive(UP_LOCATION.'temp/'.$fileid);
93            throw new UploadException(htmlspecialchars(_('Invalid archive file. The archive must contain the addon\'s xml file.')));
94        }
95    }
96
97    // Check for invalid files
98    if ($_POST['upload-type'] != 'source')
99        $invalid_files = type_check($xml_dir);
100    else
101    {
102        $xml_dir = UP_LOCATION.'temp/'.$fileid;
103        $invalid_files = type_check($xml_dir, true);
104    }
105    if (is_array($invalid_files) && count($invalid_files != 0))
106    {
107        echo '<span class="warning">'.htmlspecialchars(_('Some invalid files were found in the uploaded add-on. These files have been removed from the archive:')).' '.implode(', ',$invalid_files).'</span><br />';
108    }
109
110    if ($_POST['upload-type'] != 'source')
111    {
112        // Define addon type
113        if (preg_match('/kart\.xml$/',$xml_file))
114        {
115            $addon_type = 'karts';
116            echo htmlspecialchars(_('Upload was recognized as a kart.')).'<br />';
117        }
118        else
119        {
120            $addon_type = 'tracks';
121            echo htmlspecialchars(_('Upload was recognized as a track.')).'<br />';
122        }
123
124        // Read XML
125        $parsed_xml = read_xml($xml_file,$addon_type);
126        if (!$parsed_xml)
127        {
128            rmdir_recursive(UP_LOCATION.'temp/'.$fileid);
129            throw new UploadException(htmlspecialchars(_('Failed to read the add-on\'s XML file. Please make sure you are using the latest version of the kart or track exporter.')));
130        }
131        // Write new XML file
132        $fhandle = fopen($xml_file,'w');
133        if (!fwrite($fhandle,$parsed_xml['xml'])) {
134            echo '<span class="error">'.htmlspecialchars(_('Failed to write new XML file:')).'</span><br />';
135        }
136        fclose($fhandle);
137       
138        // Handle arenas
139        if ($parsed_xml['attributes']['arena'] == 'Y') {
140            echo htmlspecialchars(_('This track is an arena.')).'<br />';
141            $addon_type = 'arenas';
142        }
143
144        // Check for valid license file
145        $license_file = find_license(UP_LOCATION.'temp/'.$fileid);
146        if ($license_file === false)
147        {
148            rmdir_recursive(UP_LOCATION.'temp/'.$fileid);
149            throw new UploadException(htmlspecialchars(_('A valid License.txt file was not found. Please add a License.txt file to your archive and re-submit it.')));
150        }
151        $parsed_xml['attributes']['license'] = $license_file;
152
153        // Get addon id
154        $addon_id = NULL;
155        if (isset($_GET['name']))
156            $addon_id = Addon::cleanId($_GET['name']);
157        if (!preg_match('/^[a-z0-9\-]+_?[0-9]*$/i',$addon_id) || $addon_id == NULL)
158            $addon_id = Addon::generateId($addon_type,$parsed_xml['attributes']['name']);
159
160        // Save addon icon or screenshot
161        if ($addon_type == 'karts')
162        {
163            $image_file = $xml_dir.'/'.$parsed_xml['attributes']['icon-file'];
164        }
165        else
166        {
167            $image_file = $xml_dir.'/'.$parsed_xml['attributes']['screenshot'];
168        }
169        // Check if file exists
170        if (!file_exists($image_file))
171        {
172            $image_file = false;
173        }
174        if ($image_file !== false) {
175            // Get image file extension
176            preg_match('/\.([a-z]+)$/i',$image_file,$imageext);
177            // Save file
178            copy($image_file,UP_LOCATION.'images/'.$fileid.'.'.$imageext[1]);
179            $parsed_xml['attributes']['image'] = $fileid.'.'.$imageext[1];
180
181            // Record image file in database
182            $newImageQuery = 'CALL `'.DB_PREFIX.'create_file_record` '.
183                "('$addon_id','$addon_type','image','images/$fileid.{$imageext[1]}',@a)";
184            $newImageHandle = sql_query($newImageQuery);
185            if (!$newImageHandle)
186            {
187                echo '<span class="error">'.htmlspecialchars(_('Failed to associate image file with addon.')).mysql_error().'</span><br />';
188                unlink(UP_LOCATION.'images/'.$fileid.'.'.$imageext[1]);
189                $parsed_xml['attributes']['image'] = 0;
190            }
191            else
192            {       
193                $getInsertIdQuery = 'SELECT @a';
194                $getInsertIdHandle = sql_query($getInsertIdQuery);
195                if (!$getInsertIdHandle) $parsed_xml['attributes']['fileid'] = 0;
196                $iid_result = mysql_fetch_array($getInsertIdHandle);
197                // Get ID of previously inserted image
198                $parsed_xml['attributes']['image'] = $iid_result[0];
199            }
200        }
201
202        // Initialize the status flag
203        $parsed_xml['attributes']['status'] = 0;
204
205        // Check to make sure all image dimensions are powers of 2
206        if (!image_check($xml_dir))
207        {
208            echo '<span class="warning">'.htmlspecialchars(_('Some images in this add-on do not have dimensions that are a power of two.'))
209                .' '.htmlspecialchars(_('This may cause display errors on some video cards.')).'</span><br />';
210            $parsed_xml['attributes']['status'] += F_TEX_NOT_POWER_OF_2;
211        }
212       
213        $filetype = 'addon';
214    }
215    else
216    {
217        $addon_id = Addon::cleanId($_GET['name']);
218        $addon_type = mysql_real_escape_string($_GET['type']);
219        $filetype = 'source';
220    }
221
222    // Validate addon type field
223    if (!Addon::isAllowedType($addon_type))
224    {
225        rmdir_recursive(UP_LOCATION.'temp/'.$fileid);
226        throw new UploadException(htmlspecialchars(_('Invalid add-on type.')));
227    }
228
229    // Repack zip file
230    if (!repack_zip($xml_dir,UP_LOCATION.$fileid.'.zip'))
231    {
232        rmdir_recursive(UP_LOCATION.'temp/'.$fileid);
233        throw new UploadException(htmlspecialchars(_('Failed to re-pack archive file.')));
234    }
235   
236    // Record addon's file in database
237    $newAddonFileQuery = 'CALL `'.DB_PREFIX.'create_file_record` '.
238        "('$addon_id','$addon_type','$filetype','$fileid.zip',@a)";
239    $newAddonFileHandle = sql_query($newAddonFileQuery);
240    if (!$newAddonFileHandle)
241    {
242        echo '<span class="error">'.htmlspecialchars(_('Failed to associate archive file with addon.')).'</span><br />';
243        unlink(UP_LOCATION.$fileid.'.zip');
244        if ($_POST['upload-type'] != 'source')
245            $parsed_xml['attributes']['fileid'] = 0;
246    }
247    else
248    {
249        $getInsertIdQuery = 'SELECT @a';
250        $getInsertIdHandle = sql_query($getInsertIdQuery);
251        if (!$getInsertIdHandle) $parsed_xml['attributes']['fileid'] = 0;
252        $iid_result = mysql_fetch_array($getInsertIdHandle);
253        // Get ID of previously inserted file
254        if ($_POST['upload-type'] != 'source')
255            $parsed_xml['attributes']['fileid'] = $iid_result[0];
256    }
257   
258    if ($_POST['upload-type'] == 'source')
259    {
260        rmdir_recursive(UP_LOCATION.'temp/'.$fileid);
261        echo htmlspecialchars(_('Successfully uploaded source archive.')).'<br />';
262        echo '<span style="font-size: large"><a href="addons.php?type='.$addon_type.'&amp;name='.$addon_id.'">'.htmlspecialchars(_('Continue.')).'</a></span><br />';
263        return true;
264    }
265
266    // Set first revision to be "latest"
267    if ($revision == false)
268        $parsed_xml['attributes']['status'] += F_LATEST;
269
270    // Create addon
271    $addon = new coreAddon($addon_type);
272
273    // Make sure only the original uploader can make a new revision
274    if ($revision == true)
275    {
276        $addon->selectById($addon_id);
277        if (!$addon->addonCurrent)
278        {
279            rmdir_recursive(UP_LOCATION.'temp/'.$fileid);
280            throw new UploadException(htmlspecialchars(_('You are trying to add a new revision of an add-on that does not exist.')));
281        }
282        if ($_SESSION['userid'] != $addon->addonCurrent['uploader']
283                && !$_SESSION['role']['manageaddons'])
284        {
285            rmdir_recursive(UP_LOCATION.'temp/'.$fileid);
286            throw new UploadException(htmlspecialchars(_('You do not have the necessary permissions to perform this action.')));
287        }
288    }
289
290    if (!$addon->addAddon($fileid,$addon_id,$parsed_xml['attributes']))
291    {
292        echo '<span class="error">'.htmlspecialchars(_('Failed to create add-on.')).'</span><br />';
293    }
294    rmdir_recursive(UP_LOCATION.'temp/'.$fileid);
295    writeAssetXML();
296    writeNewsXML();
297    echo htmlspecialchars(_('Your add-on was uploaded successfully. It will be reviewed by our moderators before becoming publicly available.')).'<br /><br />';
298    echo '<a href="upload.php?type='.$addon_type.'&amp;name='.$addon_id.'&amp;action=file">'.htmlspecialchars(_('Click here to upload the sources to your add-on now.')).'</a><br />';
299    echo htmlspecialchars(_('(Uploading the sources to your add-on enables others to improve your work and also ensure your add-on will not be lost in the future if new SuperTuxKart versions are not compatible with the current format.)')).'<br /><br />';
300    echo '<a href="addons.php?type='.$addon_type.'&amp;name='.$addon_id.'">'.htmlspecialchars(_('Click here to view your add-on.')).'</a><br />';
301}
302
303function check_extension($filename,$type = NULL)
304{
305    // Check file-extension for uploaded file
306    if ($type == 'image')
307    {
308        if (!preg_match('/\.(png|jpg|jpeg)$/i',$filename,$fileext))
309            throw new UploadException(htmlspecialchars(_('Uploaded image files must be either PNG or Jpeg files.')));
310    }
311    else
312    {
313        // File extension must be .zip, .tgz, .tar, .tar.gz, tar.bz2, .tbz
314        if (!preg_match('/\.(zip|t[bg]z|tar|tar\.gz|tar\.bz2)$/i',$filename,$fileext))
315            throw new UploadException(htmlspecialchars(_('The file you uploaded was not the correct type.')));
316    }
317    return $fileext[1];
318}
319
320function extract_archive($file,$destination,$fileext = NULL)
321{
322    if (!file_exists($file))
323    {
324        echo '<span class="error">'.htmlspecialchars(_('The file to extract does not exist.')).'</span><br />';
325    }
326
327    if ($fileext == NULL)
328        $fileext = pathinfo($file, PATHINFO_EXTENSION);
329
330    // Extract archive
331    switch ($fileext) {
332        // Handle archives using ZipArchive class
333        case 'zip':
334            $archive = new ZipArchive;
335            if (!$archive->open($file)) {
336                echo '<span class="error">'.htmlspecialchars(_('Could not open archive file. It may be corrupted.')).'</span><br />';
337                unlink($file);
338                return false;
339            }
340            if (!$archive->extractTo($destination))
341            {
342                echo '<span class="error">'.htmlspecialchars(_('Failed to extract archive file.')).' (zip)</span><br />';
343                unlink($file);
344                return false;
345            }
346            $archive->close();
347            unlink($file);
348            break;
349
350        // Handle archives using Archive_Tar class
351        case 'tar':
352        case 'tar.gz':
353        case 'tgz':
354        case 'gz':
355        case 'tbz':
356        case 'tar.bz2':
357        case 'bz2':
358            require_once('Archive/Tar.php');
359            $compression = NULL;
360            if ($fileext == 'tar.gz' || $fileext == 'tgz' || $fileext == 'gz')
361            {
362                $compression = 'gz';
363            }
364            elseif ($fileext == 'tbz' || $fileext == 'tar.bz2' || $fileext == 'bz2')
365            {
366                $compression = 'bz2';
367            }
368            $archive = new Archive_Tar($file, $compression);
369            if (!$archive)
370            {
371                echo '<span class="error">'.htmlspecialchars(_('Could not open archive file. It may be corrupted.')).'</span><br />';
372                unlink($file);
373                return false;
374            }
375            if (!$archive->extract($destination))
376            {
377                echo '<span class="error">'.htmlspecialchars(_('Failed to extract archive file.')).' ('.$compression.')</span><br />';
378                unlink($file);
379                return false;
380            }
381            unlink($file);
382            break;
383
384        default:
385            echo '<span class="error">'.htmlspecialchars(_('Unknown archive type.')).'</span><br />';
386            unlink($file);
387            return false;
388    }
389    return true;
390}
391
392function file_upload_error($upload)
393{
394    if (!is_array($upload))
395    {
396        return htmlspecialchars(_('Upload is invalid.'));
397    }
398    switch ($upload['error'])
399    {
400        default:
401            return htmlspecialchars(_('Unknown file upload error.'));
402        case UPLOAD_ERR_OK:
403            return false;
404        case UPLOAD_ERR_INI_SIZE:
405            return htmlspecialchars(_('Uploaded file is too large.'));
406        case UPLOAD_ERR_FORM_SIZE:
407            return htmlspecialchars(_('Uploaded file is too large.'));
408        case UPLOAD_ERR_PARTIAL:
409            return htmlspecialchars(_('Uploaded file is incomplete.'));
410        case UPLOAD_ERR_NO_FILE:
411            return htmlspecialchars(_('No file was uploaded.'));
412        case UPLOAD_ERR_NO_TMP_DIR:
413            return htmlspecialchars(_('There is no TEMP directory to store the uploaded file in.'));
414        case UPLOAD_ERR_CANT_WRITE:
415            return htmlspecialchars(_('Unable to write uploaded file to disk.'));
416    }
417}
418
419function find_xml($dir)
420{
421    if(is_dir($dir))
422    {
423        foreach(scandir($dir) as $file)
424        {
425            if(is_dir($dir."/".$file) && $file != "." && $file != "..")
426            {
427                $name = find_xml($dir."/".$file);
428                if($name != false)
429                {
430                    return $name;
431                }
432            }
433            else if(file_exists($dir."/kart.xml"))
434            {
435                return $dir."/kart.xml";
436            }
437            else if(file_exists($dir."/track.xml"))
438            {
439                return $dir."/track.xml";
440            }
441        }
442    }
443    return false;
444}
445
446function find_license($dir)
447{
448    if(is_dir($dir))
449    {
450        foreach(scandir($dir) as $file)
451        {
452            // Check recursively
453            if(is_dir($dir."/".$file) && $file != "." && $file != "..")
454            {
455                $name = find_license($dir."/".$file);
456                // The file was found in a recursive lookup
457                if($name != false)
458                {
459                    return $name;
460                }
461            }
462            else if(file_exists($dir.'/License.txt'))
463            {
464                return file_get_contents($dir.'/License.txt');
465            }
466            else if (file_exists($dir.'/license.txt'))
467            {
468                return file_get_contents($dir.'/license.txt');
469            }
470        }
471    }
472    return false;
473}
474
475function read_xml($file,$type)
476{
477    // Can't use XMLReader because we don't know the names of all our attributes
478    $reader = xml_parser_create();
479
480    // Remove whitespace at beginning and end of file
481    $xmlContents = trim(file_get_contents($file));
482    // Remove amperstands (&) because they cause problems
483    $xmlContents = str_replace('& ','&amp; ',$xmlContents);
484
485    if (!xml_parse_into_struct($reader,$xmlContents,$vals,$index))
486    {
487        echo 'XML Error: '.xml_error_string(xml_get_error_code($reader)).'<br />';
488        return false;
489    }
490
491    // Set up the XMLWriter to modify the XML file
492    $writer = new XMLWriter();
493    $writer->openMemory();
494    $writer->startDocument('1.0');
495    $writer->setIndent(true);
496    $writer->setIndentString('    ');
497
498    $groups_found = false;
499    $attributes = array();
500    // Cycle through all of the xml file's elements
501    foreach ($vals AS $val)
502    {
503        if ($val['type'] == 'close')
504        {
505            $writer->endElement();
506            continue;
507        }
508        if ($val['type'] == 'open' || $val['type'] == 'complete')
509            $writer->startElement(strtolower($val['tag']));
510        if (isset($val['attributes']))
511        {
512            foreach ($val['attributes'] AS $attribute => $value)
513            {
514                // XML parser returns tag names in all uppercase
515                if (strtolower($val['tag']).'s' == $type)
516                {
517                    $attribute = strtolower($attribute);
518                    if ($attribute != 'groups')
519                    {
520                        $attributes[$attribute] = $value;
521                    }
522                    else
523                    {
524                        $attributes[$attribute] = 'Add-Ons';
525                        $value = 'Add-Ons';
526                    }
527                }
528                $writer->writeAttribute(strtolower($attribute),$value);
529            }
530        }
531        if ($val['type'] == 'complete')
532            $writer->endElement();
533    }
534    $writer->endDocument();
535    $new_xml = $writer->flush();
536
537    // Make sure certain attributes exist
538    if (!array_key_exists('arena',$attributes))
539        $attributes['arena'] = '0';
540    if (!array_key_exists('designer',$attributes))
541        $attributes['designer'] = '';
542
543    return array('xml'=>$new_xml,'attributes'=>$attributes);
544}
545
546function image_check($path)
547{
548    if (!file_exists($path))
549        return false;
550    if (!is_dir($path))
551        return false;
552    // Check supported image types
553    $imagetypes = imagetypes();
554    $imageFileExts = array();
555    if ($imagetypes & IMG_GIF)
556        $imageFileExts[] = 'gif';
557    if ($imagetypes & IMG_PNG)
558        $imageFileExts[] = 'png';
559    if ($imagetypes & IMG_JPG)
560    {
561        $imageFileExts[] = 'jpg';
562        $imageFileExts[] = 'jpeg';
563    }
564    if ($imagetypes & IMG_WBMP)
565        $imageFileExts[] = 'wbmp';
566    if ($imagetypes & IMG_XPM)
567        $imageFileExts[] = 'xpm';
568
569
570    foreach (scandir($path) AS $file)
571    {
572        // Don't check current and parent directory
573        if ($file == '.' || $file == '..')
574            continue;
575        // Make sure the whole path is there
576        $file = $path.'/'.$file;
577        // Dig into deeper directories
578        if (is_dir($file)) {
579            if (!image_check($file))
580                return false;
581            continue;
582        }
583        // Don't check files that aren't images
584        if (!preg_match('/\.('.implode('|',$imageFileExts).')$/i',$file))
585            continue;
586
587        // If we're still in the loop, there is an image to check
588        $image_size = getimagesize($file);
589        // Make sure dimensions are powers of 2
590        if (($image_size[0] & ($image_size[0]-1)) || ($image_size[0] <= 0))
591            return false;
592        if (($image_size[1] & ($image_size[1]-1)) || ($image_size[1] <= 0))
593            return false;
594    }
595
596
597    return true;
598}
599
600function type_check($path, $source = false)
601{
602    if (!file_exists($path))
603        return false;
604    if (!is_dir($path))
605        return false;
606    // Make a list of approved file types
607    if ($source === false)
608        $approved_types = ConfigManager::get_config('allowed_addon_exts');
609    else
610        $approved_types = ConfigManager::get_config('allowed_source_exts');
611    $approved_types = explode(',',$approved_types);
612    $removed_files = array();
613
614    foreach (scandir($path) AS $file)
615    {
616        // Don't check current and parent directory
617        if ($file == '.' || $file == '..')
618            continue;
619        // Make sure the whole path is there
620        $file = $path.'/'.$file;
621        // Dig into deeper directories
622        if (is_dir($file))
623        {
624            $dir_result = type_check($file, $source);
625            if (is_array($dir_result))
626            {
627                foreach ($dir_result AS $result)
628                {
629                    $removed_files[] = $result;
630                }
631            }
632            continue;
633        }
634        // Remove files with unapproved extensions
635        if (!preg_match('/\.('.implode('|',$approved_types).')$/i',$file))
636        {
637            $removed_files[] = basename($file);
638            unlink($file);
639        }
640    }
641    if (count($removed_files) == 0)
642        return true;
643    return $removed_files;
644}
645
646function repack_zip($path_zip, $to)
647{
648    $zip = new ZipArchive();
649    $filename = $to;
650
651    if(file_exists($filename))
652        unlink($filename);
653
654    if ($zip->open($filename, ZIPARCHIVE::CREATE)!==TRUE)
655    {
656        echo("Cannot open <$filename>\n");
657        return false;
658    }
659    repack_internal($zip, $path_zip);
660    $succes = $zip->close();
661    if(!$succes)
662    {
663        echo "Can't close the zip\n";
664        return false;
665    }
666    return true;
667}
668
669function repack_internal($zip, $path_zip)
670{
671    foreach(scandir($path_zip) as $file)
672    {
673        if($file == ".." || $file == ".")
674            continue;
675        if(is_dir($path_zip."/".$file))
676        {
677            // Skip over .svn directories that may exist
678            if (preg_match('/\.svn$/i',$path_zip.'/'.$file))
679                continue;
680            repack_internal($zip, $path_zip."/".$file);
681        }
682        else if(!$zip->addFile($path_zip."/".$file, $file))
683        {
684            echo "Can't add this file: ".$file."\n";
685            return false;
686        }
687        if(!file_exists($path_zip."/".$file))
688        {
689            echo "Can't add this file (it doesn't exist): ".$file."\n";
690            return false;
691        }
692    }
693}
694?>
Note: See TracBrowser for help on using the browser.