Index: kmz_2_tri.php
===================================================================
--- kmz_2_tri.php	(revision 1040)
+++ kmz_2_tri.php	(revision 1041)
@@ -0,0 +1,711 @@
+<?php
+/*
+    Raydium - CQFD Corp.
+    http://raydium.org/
+    Released under both BSD license and Lesser GPL library license.
+    See "license.txt" file.
+*/
+// Sketchup embeded Collada 1.4.1 file converter to raydium 1 .tri format file.
+// This script convert only the first Scene.
+// Run recursively into the scene hierarchy.
+// Export all meshes in one .tri file.
+// Size of generated file is generaly big, number of texture can
+// exceed raydium capacity on big models.
+//
+// $file_name (input kmz/dae/tri file name) $force_scale(input convert scale applied to all meshes) $verbose(input verbose level).
+
+if (empty($file_name))
+    {
+    //$file_name="test.tri";
+    //$file_name="test.dae";
+    //$file_name="city.dae";
+    //$file_name="tele.kmz";
+    $file_name="";
+    die("kmz_2_tri: ERROR: empty file name! the world will explode !");
+    }
+
+if (empty($force_scale))
+    $force_scale=1;
+
+if (empty($verbose))
+    $verbose=0;
+
+if (!file_exists($file_name))
+    {
+    $file_name="";
+    die("kmz_2_tri: ERROR: File '$file_name' not found.");
+    }
+
+dprint(0,"kmz_2_tri: Converting: ".$file_name);
+
+$dest_path=dirname($file_name);
+
+$dae_file=dae_file_name($file_name);
+$source_path=dirname($dae_file);
+$xml_file=convert_xml_iso($dae_file);
+
+$dom = new DomDocument;
+
+if (!$dom->load($xml_file))
+    {
+    $file_name="";
+    die("kmz_2_tri: Invalid dae/xml file. Please try again.");
+    }
+
+$xpath = new DOMXpath($dom);
+$res=$xpath->query("//COLLADA/*");
+if ($res->length==0)
+    {
+    echo "kmz_2_tri: ERROR: Xpath doesn't work. Verify utf8 encoding, schema definition in dae header ...\n";
+    echo "kmz_2_tri: Sorry script can't go further as is.\n";
+    $file_name="";
+    die(-1);
+    }
+$out_file=$dest_path."/".filename($dae_file).".tri";
+dprint(0,"kmz_2_tri: Output file: ".$out_file);
+$ftri=fopen($out_file,"w");
+fprintf($ftri,"1\n");
+
+$visual_scene_url=get_attribute("/scene/instance_visual_scene","url");
+$scene_nodes=find_attribute("/library_visual_scenes/visual_scene","id",$visual_scene_url);
+$scene_nodes=get_childs($scene_nodes);
+
+$matrix=set_identity();
+$n=export_nodes($scene_nodes,$matrix,$scene_nodes);
+
+fclose($ftri);
+kmz_unzip_remove();
+$file_name=$ftri;
+die(0);
+
+//******************************************************************************
+function export_nodes($nodes,$matrixin,$from_node)
+    {
+
+    foreach($nodes as $node)
+        {
+        if ($node->nodeType==XML_TEXT_NODE) continue;
+        if ($node->tagName=="node")
+            {
+            dprint(4,"kmz_2_tri:->Entering Sub Node:".$node->getAttribute("name"));
+            export_nodes(get_childs($node),$matrixin,$node);
+            dprint(4,"kmz_2_tri:<-Leaving Sub Node:".$node->getAttribute("name"));
+            }
+        if ($node->tagName=="instance_node")
+            {
+            $nodep=$node->parentNode;
+            $matrix = set_identity();
+            $matrix = matrix($nodep,$matrix);
+            $matrix = translate($nodep,$matrix);
+            $matrix = rotate($nodep,$matrix);
+            $matrix = scale($nodep,$matrix);
+            $matrixout=mat_mul($matrixin,$matrix);
+
+            $nnode=get_attribute("","url",$node);
+
+            $nnode=find_attribute("/library_nodes/node","id",$nnode);
+            $nnodes=get_childs($nnode);
+            export_nodes($nnodes,$matrixout,$node);
+            }
+        if ($node->tagName=="instance_geometry")
+            {
+            $nodep=$node->parentNode;
+            $matrix = set_identity();
+            $matrix = matrix($nodep,$matrix);
+            $matrix = translate($nodep,$matrix);
+            $matrix = rotate($nodep,$matrix);
+            $matrix = scale($nodep,$matrix);
+            $matrixout=mat_mul($matrixin,$matrix);
+
+            $geom=get_attribute("","url",$node);
+            $meshs=find_attribute("/library_geometries/geometry","id",$geom);
+            $mesh=find_one("mesh",$meshs);
+            dprint(2,"kmz_2_tri:Exporting mesh:".$meshs->getAttribute("name"));
+            $nverts=export_mesh($mesh,$matrixout,$node);
+            dprint(2,"kmz_2_tri: ".$meshs->getAttribute("name")." ".$nverts." vertices.");
+            }
+        }
+    }
+function export_mesh($mesh,$matrix,$from_node)
+    {
+    global $vxyz,$vxyz_offset,$vnxyz,$vnxyz_offset,$uv_array,$uv_offset,$has_uv;
+    global $faces_indexes,$interleave;
+    $nverts=0;
+    $triangles=find("triangles",$mesh);
+    foreach($triangles as $triangle)
+        {
+        $texture = texture($triangle,$from_node);
+        $input_vectors=find("input",$triangle);
+        $interleave=interleave($input_vectors);
+        $vxyz=$vnxyz=$uv_array=array();
+        parse_inputs($mesh,$input_vectors,$vxyz,$vxyz_offset,$vnxyz,$vnxyz_offset,$uv_array,$uv_offset,$has_uv);
+        $vxyz=vertices_transform($vxyz,$matrix);
+
+        $faces_indexes=find_one("p",$triangle);
+        $faces_indexes=get_value($faces_indexes);
+        $faces_indexes=explode(" ",$faces_indexes);
+        $n=(sizeof($faces_indexes)-1) /$interleave;
+        for ($indx=0;$indx<$n;$indx++)
+            write_vert($indx,$texture);
+        $nverts+=$n;
+
+        }
+
+    $polys=find("polylist",$mesh);
+    foreach($polys as $poly)
+        {
+        $texture = texture($poly,$from_node);
+        $input_vectors=find("input",$poly);
+        $interleave=interleave($input_vectors);
+        $vxyz=$vnxyz=$uv_array=array();
+        parse_inputs($mesh,$input_vectors,$vxyz,$vxyz_offset,$vnxyz,$vnxyz_offset,$uv_array,$uv_offset,$has_uv);
+        $vxyz=vertices_transform($vxyz,$matrix);
+
+        $faces_nvertex=find_one("vcount",$poly);
+        $faces_nvertex=get_value($faces_nvertex);
+        $faces_indexes=find_one("p",$poly);
+        $faces_indexes=get_value($faces_indexes);
+        $faces_nvertex=explode(" ",$faces_nvertex);
+        $faces_indexes=explode(" ",$faces_indexes);
+
+        $j=0;
+        foreach($faces_nvertex as $face_n)
+            {
+            if ($face_n==4)
+                {
+                $indx=array(0,1,2,2,3,0);
+                for ($i=0;$i<6;$i++)
+                    {
+                    //Creating to triangle 0-1-2 and 2-3-0
+                    $v=$j+$indx[$i];
+                    write_vert($v,$texture);
+                    }
+                $j+=4;
+                $nverts+=4;
+                }
+            if ($face_n==3)
+                {
+                for ($i=0;$i<3;$i++)
+                    write_vert($j+$i,$texture);
+                $j+=3;
+                $nverts+=3;
+                }
+            }
+        }
+    return $nverts;
+    }
+
+function interleave($inputs)
+    {
+    $max_offset=0;
+    foreach($inputs as $input)
+    $max_offset = max($max_offset,$input->getAttribute("offset"));
+    return $max_offset+1;
+    }
+function parse_inputs($mesh,$input_vectors,&$vxyz,&$vxyz_offset,&$vnxyz,&$vnxyz_offset,&$uv_array,&$uv_offset,&$has_uv)
+    {
+
+    $has_uv=False;
+    foreach($input_vectors as $input)
+        {
+        if (get_attribute("","semantic",$input)=="VERTEX")
+            {
+            $vxyz_offset=get_attribute("","offset",$input);
+
+            $v1=get_attribute("","source",$input);
+
+            $v=find_attribute("vertices","id",$v1,$mesh);
+            $inputv=get_attribute("input","source",$v);
+
+            $source=find_attribute("source","id" ,$inputv,$mesh);
+            $float_array=find_one("float_array",$source);
+            $vcount=get_attribute("","count",$float_array);
+            $vposvals=get_value($float_array);
+            $xyzpos=explode(" ",$vposvals);
+
+            $j=0;
+            for ($i=0;$i<$vcount;$i+=3)
+                {
+                $vxyz[$j][0]=$xyzpos[$i];
+                $vxyz[$j][1]=$xyzpos[$i+1];
+                $vxyz[$j][2]=$xyzpos[$i+2];
+                $j++;
+                }
+            }
+        if (get_attribute("","semantic",$input)=="NORMAL")
+            {
+            $vnxyz_offset=get_attribute("","offset",$input);
+            $v1=get_attribute("",'source',$input);
+
+            $float_array=find_attribute("source","id",$v1,$mesh);
+            $float_array=find_one("float_array",$float_array);
+            $vcount=get_attribute("","count",$float_array);
+            $vnormvals=get_value($float_array);
+            $nxyzpos=explode(" ",$vnormvals);
+
+            $j=0;
+            for ($i=0;$i<$vcount;$i+=3)
+                {
+                $vnxyz[$j][0]=$nxyzpos[$i];
+                $vnxyz[$j][1]=$nxyzpos[$i+1];
+                $vnxyz[$j][2]=$nxyzpos[$i+2];
+                $j++;
+                }
+
+            }
+        if (get_attribute("","semantic",$input)=="TEXCOORD")
+            {
+            $uv_offset=get_attribute("","offset",$input);
+            $v1=get_attribute("",'source',$input);
+
+            $float_array=find_attribute("source","id",$v1,$mesh);
+            $float_array=find_one("float_array",$float_array);
+            $vcount=get_attribute("","count",$float_array);
+            $uvvals=get_value($float_array);
+            $uv=explode(" ",$uvvals);
+
+            $j=0;
+            for ($i=0;$i<$vcount;$i+=2)
+                {
+                $uv_array[$j][0]=$uv[$i];
+                $uv_array[$j][1]=$uv[$i+1];
+                $j++;
+                }
+            $has_uv=True;
+            }
+        }
+    }
+function texture($node,$from_node)
+    {
+    global $source_path,$dest_path,$file_name;
+    $mat_id=get_attribute("",'material',$node);
+    if ($mat_id==NULL || $mat_id=="")
+        {
+        return "rgb(0.6,0.6,0.6)";
+        }
+    $target=find_attribute("bind_material/technique_common/instance_material","symbol",$mat_id,$from_node);
+    $target=get_attribute("","target",$target);
+
+    $effect=find_attribute("/library_materials/material","id",$target);
+    $effect=find_one("instance_effect",$effect);
+    $url=get_attribute("","url",$effect);
+
+    $effect=find_attribute("/library_effects/effect","id",$url);
+
+    $profile=find_one("*/technique/lambert/diffuse/*",$effect);
+
+
+    if ($profile->tagName=='color')
+        {
+        $rgb=$profile->nodeValue;
+        $rgb=explode(' ',$rgb);
+        return sprintf("rgb(%3.3f,%3.3f,%3.3f)",$rgb[0],$rgb[1],$rgb[2]);
+        }
+
+    if ($profile->tagName=='texture')
+        {
+        $sid=get_attribute("","texture",$profile);
+        $sampler=find_attribute("*/newparam","sid",$sid,$effect);///surface/init_from
+
+        $sid=get_value($sampler);
+        $surface=find_attribute("*/newparam","sid",$sid,$effect);
+        $sid=get_value($surface);
+        $image=find_attribute("/library_images/image","id",$sid);
+        $image=get_value($image);
+
+        $source_file_name=$source_path."/".$image;
+
+        $dest_file_name=$dest_path."/".filename($file_name)."_".filename($image).".tga";
+
+        if (!file_exists($dest_file_name))
+            {
+            convtga($source_file_name,$dest_file_name);
+            }
+
+        if (file_exists($dest_file_name))
+            return basename($dest_file_name);
+        else
+            return "rgb(0.2,0.2,0.2)";
+
+        return $image;
+        }
+    }
+
+function convtga($img,$image)
+    {
+    if(!is_callable(gd_info))
+        return;
+
+    $flip=False;
+    dprint(0,"Converting and scaling:".basename($img)." to ".$image);
+    $ext=pathinfo($img);
+    if ($ext['extension']=='jpg')
+        {
+        $ims=imagecreatefromjpeg($img);
+        }
+    if ($ext['extension']=='png')
+        {
+        $ims=imagecreatefrompng($img);
+        $flip=True;
+        }
+
+    $sx=imagesx($ims);
+    $sy=imagesy($ims);
+
+    $psx=pow(2,floor(log($sx,2)));
+    $psy=pow(2,floor(log($sy,2)));
+
+    $imr=imagecreatetruecolor($psx,$psy);
+    imagealphablending($imr,False);
+
+    imagecopyresampled($imr,$ims ,0,0,0,0,$psx ,$psy ,$sx ,$sy);
+
+
+    $imd=fopen($image,"wb");
+    $fh=sprintf("\000\000\002\000\000\000\000\000\000\000\000\000%c%c%c%c\040\000",$psx%256,floor($psx/256),$psy%256,floor($psy/256));
+    fwrite($imd,$fh,18);
+    for ($i=0;$i<$psy;$i++)
+        {
+        for ($j=0;$j<$psx;$j++)
+            {
+
+            $rgb = imagecolorat($imr, $j, $psy-$i-1);
+
+            $a = ($rgb >> 24) &0xFF;
+            $r = ($rgb >> 16) & 0xFF;
+            $g = ($rgb >> 8) & 0xFF;
+            $b = $rgb & 0xFF;
+            if ($a==0)
+                $a=255;
+            else
+                $a=0;
+            $d=sprintf("%c%c%c%c",$b,$g,$r,$a);
+            fwrite($imd,$d,4);
+            }
+        //dprint($i);
+        }
+
+    fclose($imd);
+    }
+
+function vertices_transform($vixyz,$matrix)
+    {
+    for ($i=0;$i<sizeof($vixyz);$i++)
+        {
+        for ($j=0;$j<3;$j++)
+            {
+            $vxyz[$i][$j]=$matrix[$j][0]*$vixyz[$i][0]+$matrix[$j][1]*$vixyz[$i][1]+$matrix[$j][2]*$vixyz[$i][2]+$matrix[$j][3];
+            }
+        }
+    return $vxyz;
+    }
+function write_vert($indx,$material_name)
+    {
+    global $faces_indexes,$vxyz_offset,$vnxyz_offset,$uv_offset;
+    global $vxyz,$vnxyz,$uv_array,$interleave,$has_uv;
+    global $ftri,$force_scale;
+
+    $vert_indx=$faces_indexes[$indx*$interleave+$vxyz_offset];
+    $vert_nindex=$faces_indexes[$indx*$interleave+$vnxyz_offset];
+    if ($has_uv)
+        $vert_uv_indx=$faces_indexes[$indx*$interleave+$uv_offset];
+
+    $li=sprintf("%+9.9f %+9.9f %+9.9f ",$vxyz[$vert_indx][0]*$force_scale,$vxyz[$vert_indx][1]*$force_scale,$vxyz[$vert_indx][2]*$force_scale);
+    $li.=sprintf("%+6.6f %+6.6f %+6.6f ",$vnxyz[$vert_nindex][0],$vnxyz[$vert_nindex][1],$vnxyz[$vert_nindex][2]);
+    if ($has_uv)
+        $li.=sprintf("%+6.6f %+6.6f ",$uv_array[$vert_uv_indx][0],$uv_array[$vert_uv_indx][1]);
+    else
+        $li.=sprintf("%+6.6f %+6.6f ",0,0);
+    $li.=$material_name;
+
+    fprintf($ftri,$li."\n");
+    }
+
+function set_identity()
+    {
+    for ($i=0;$i<4;$i++)
+        for ($j=0;$j<4;$j++)
+            if ($i==$j)
+                $matrix[$i][$j]=1;
+            else
+                $matrix[$i][$j]=0;
+    return $matrix;
+    }
+function mat_mul($ma,$mb)
+    {
+    for ($i=0;$i<4;$i++)
+        for ($j=0;$j<4;$j++)
+            $mr[$i][$j]=$ma[$i][0]*$mb[0][$j]+$ma[$i][1]*$mb[1][$j]+$ma[$i][2]*$mb[2][$j]+$ma[$i][3]*$mb[3][$j];
+    return $mr;
+
+    }
+
+function matrix($node,$matrix)
+    {
+    $matrix1=find_node("matrix",$node);
+    if ($matrix1==NULL)
+        return $matrix;
+    $matrix1=$matrix1->nodeValue;
+    $matrix2=$matrix1;
+    do
+        {
+        $matrix1=$matrix2;
+        $matrix2=str_replace("  "," ",$matrix2);
+        $matrix2=str_replace("\n"," ",$matrix2);
+        $matrix2=str_replace("\r"," ",$matrix2);
+        }
+    while ($matrix2!=$matrix1);
+    $matrix1=explode(' ',trim($matrix2));
+
+    for ($i=0;$i<4;$i++)
+        for ($j=0;$j<4;$j++)
+            $matrix[$i][$j]=$matrix1[$i*4+$j];
+    return $matrix;
+    }
+function translate($node,$matrix)
+    {
+    $mesh_postag=find_node("translate",$node);
+    if ($mesh_postag===NULL)
+        return $matrix;
+    $mesh_pos=explode(" ",$mesh_postag->nodeValue);
+    for ($i=0;$i<3;$i++)
+        $matrix[$i][3]=$mesh_pos[$i];
+    return $matrix;
+    }
+function rotate($node,$matrix)
+    {
+    $mesh_rots=find_nodes("rotate",$node);
+    $rx=$ry=$rz=0;
+    if ($mesh_rots===NULL)
+        return $matrix;
+    foreach($mesh_rots as $rot)
+        {
+        $axes=$rot->nodeValue;
+        $axes=explode(" ",$axes);
+        if ($axes[0]!=0) $rx=$axes[3]*pi()/180;
+        if ($axes[1]!=0) $ry=$axes[3]*pi()/180;
+        if ($axes[2]!=0) $rz=$axes[3]*pi()/180;
+        }
+
+    $sx = sin($rx);             // Setup - une seule fois
+    $cx = cos($rx);
+    $sy = sin($ry);
+    $cy = cos($ry);
+    $sz = sin($rz);
+    $cz = cos($rz);
+    $matrix[0][0]=$cz*$cy;
+    $matrix[0][1]=$cz*$sy*$sx-$sz*$cx;
+    $matrix[0][2]=$sz*$sx+$cz*$sy*$cx;
+    $matrix[1][0]=$sz*$cy;
+    $matrix[1][1]=$cz*$cx+$sz*$sy*$sx;
+    $matrix[1][2]=$sz*$sy*$cx-$cz*$sx;
+    $matrix[2][0]=-$sy;
+    $matrix[2][1]=$cy*$sx;
+    $matrix[2][2]=$cy*$cx;
+    return $matrix;
+    }
+function scale($node,$matrix)
+    {
+    $mesh_scale=find_node("scale",$node);
+    if ($mesh_scale===NULL)
+        return $matrix;
+
+    $mesh_scale=explode(" ",$mesh_scale->nodeValue);
+    for ($i=0;$i<3;$i++)
+        for ($j=0;$j<3;$j++)
+            $matrix[$i][$j]=$matrix[$i][$j]*$mesh_scale[$j];
+    return $matrix;
+    }
+
+function get_value($node)
+    {
+    return trim($node->nodeValue);
+    }
+function get_attribute($path,$attribute,$rel=NULL)
+    {
+    if ($path!="")
+        $rel=find_one($path,$rel);
+    $res=$rel->getAttribute($attribute);
+    $res=explode('#',$res);
+    $res=$res[count($res)-1];
+    return $res;
+    }
+function get_childs($node)
+    {
+    $res = find("child::*",$node);
+    return $res;
+    }
+function find($query,$rel=NULL)
+    {
+    global $xpath;
+    if ($rel===NULL)
+        $ret=$xpath->query("/COLLADA".$query);
+    else
+        $ret=$xpath->query($query,$rel);
+    return $ret;
+    }
+function find_attribute($where,$attribute,$value,$rel=NULL)
+    {
+    $query=$where."[@".$attribute."='".$value."']";
+    $res=find_one($query,$rel);
+    return $res;
+    }
+function find_one($tag,$rel=NULL)
+    {
+    $r=find($tag,$rel);
+    if ($r->length>1)
+        {
+        dprint(0,"Structural problem, found ".$r->length." tags ".$tag." only one expected.");
+        }
+    return $r->item(0);
+    }
+function find_node($tag,$rel=NULL)
+    {
+    $r=find($tag,$rel);
+    if ($r->length==0)
+        {
+        return NULL;
+        }
+    return $r->item(0);
+    }
+function find_nodes($tag,$rel=NULL)
+    {
+    $r=find($tag,$rel);
+    if ($r->length==0)
+        {
+        return NULL;
+        }
+    return $r;
+    }
+
+function convert_xml_iso($f)
+    {
+    //Quick and dirty utf8 change for xpath !!!!!
+    $fin=fopen($f,"r");
+    $xml_file=dirname($f)."/".filename($f).".xml";
+    $fout=fopen($xml_file,"w");
+    $c=fgets($fin);
+    $c="<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n";
+    fputs($fout,$c);
+    $c=fgets($fin);
+    $c="<COLLADA>\n";
+    fputs($fout,$c);
+    while (!feof($fin))
+        {
+        $c=fgets($fin);
+        fputs($fout,$c);
+        }
+    fclose($fin);
+    fclose($fout);
+    return $xml_file;
+    }
+function dae_file_name($file_name)
+    {
+    $file_name=clean_path($file_name);
+
+    if (extension($file_name)==='kmz')
+        {
+        $source_path=kmz_unzip($file_name);
+        $dae_file=$source_path."/models/".filename($file_name).".dae";
+        }
+    if (extension($file_name)==='dae')
+        {
+        $dae_file=$file_name;
+        }
+    if (extension($file_name)==='tri')
+        {
+        dprint(0,"Already .tri file.");
+        die(0);
+        }
+    if (extension($file_name)==='xml')
+        {
+        $dae_file=$file_name;
+        }
+    return $dae_file;
+    }
+function clean_path($p)
+    {
+    while (($pos=strpos($p,"\\"))!==False)
+        $p[$pos]='/';
+    return $p;
+    }
+function extension($f)
+    {
+    return pathinfo($f,PATHINFO_EXTENSION);
+    }
+function filename($f)
+    {
+    return pathinfo($f,PATHINFO_FILENAME);
+    }
+
+function dprint($lvl,$a)
+    {
+    global $verbose;
+    if ($lvl<=$verbose)
+        {
+        echo $a;
+        //echo " <br>\n";
+        }
+    }
+function xmlprint($a)
+    {
+    $Body = $a;//->ownerDocument->documentElement->firstChild;
+    $Document = new DOMDocument();
+    $Document->appendChild($Document->importNode($Body,true));
+    dprint($Document->saveHTML());
+    }
+
+function kmz_unzip($kmz_filen)
+    {
+
+    $tmpfile = tempnam("kmz","");
+    $path = dirname($tmpfile);
+    unlink($tmpfile);
+    dprint(2,"kmz_2_tri: Working temp dir:".$path);
+    $pathkmz=$path."/kmz";
+    // Sous php edit ne pas oublier d'ajouter l'extension zip_php dans php.ini
+    $zip= new ZipArchive;
+    $zip->open($kmz_filen);
+    $zip->extractTo($pathkmz);
+    $zip->close();
+
+    return $pathkmz;
+    }
+function kmz_unzip_remove()
+    {
+    $tmpfile = tempnam("kmz","");
+    $path = dirname($tmpfile);
+    unlink($tmpfile);
+    $pathkmz=$path."/kmz";
+    recursive_remove_directory($pathkmz);
+    }
+function recursive_remove_directory($directory, $empty=FALSE)
+    {
+    if (substr($directory,-1) == '/')
+        $directory = substr($directory,0,-1);
+    if (!file_exists($directory) || !is_dir($directory))
+        return FALSE;
+    elseif(is_readable($directory))
+        {
+        $handle = opendir($directory);
+        while (FALSE !== ($item = readdir($handle)))
+            {
+            if ($item != '.' && $item != '..')
+                {
+                $path = $directory.'/'.$item;
+                if (is_dir($path))
+                    recursive_remove_directory($path);
+                else
+                    unlink($path);
+                }
+            }
+        closedir($handle);
+        if ($empty == FALSE)
+            {
+            if (!rmdir($directory))
+                return FALSE;
+            }
+        }
+    return TRUE;
+    }
+?>
\ No newline at end of file