<?php
/**
* Filesystem function
*
* This file includes functions related to files and directories
* @package eFront
*/

/**
* Returns the extension of the designated filename
*
* This simple function is used to find the extension of a file. Its input is the file name
* and it returns a string containing the extension.
* <br/>Example:
* <code>
* $ext = eF_getFileExtension("test.txt");
* //$ext now contains "txt"
* </code>
* If the file doesn't have any extension, the string returned is empty
*
* @param string $filename The file name
* @return string The file extension
* @version 1.0
* @todo filesystem
*/
function eF_getFileExtension($filename) 
{
    return pathinfo($filename, PATHINFO_EXTENSION);
}

/**
* Returns the contents of a directory
*
* This function accepts a directory name and returns an array where the elements are 
* the full paths to every file in it, recursively. If the second parameter is specified, 
* then only files of the specified type are returned. If no argument is specified, it searches 
* the current directory and returns every file in it.
* <br/>Example:
* <code>
* $file_list = eF_getDirContents();                 //return current directory contents
* $file_list = eF_getDirContents('/tmp');           //return /tmp directory contents
* $file_list = eF_getDirContents(false, 'php');     //return files with extension php in the current directory and subdirectories
* $file_list = eF_getDirContents(false, array('php', 'html'));     //return files with extension php or html in the current directory and subdirectories
* </code>
*
* @param string $dir The directory to recurse into
* @param mixed $ext Return only files with extension $ext, or in array $ext
* @param bool $get_dir If false, do not append directory information to files
* @param bool $recurse Whether to recurse into subdirectories
* @return array An array with every file and directory inside the directory specified
* @version 1.8
* Changes from version 1.7 to 1.8 (2007/08/10 - peris):
* - Exclude .svn folder from return list
* Changes from version 1.6 to 1.7 (2007/07/30 - peris):
* - Now, it returns directory names along with file names
* Changes from version 1.5 to 1.6 (2007/07/26 - peris):
* - Added $recurse parameter
* Changes from version 1.3 to 1.4 (2007/03/26 - peris):
* - Added $get_dir parameter
* Changes from version 1.2 to 1.3 (2007/03/25 - peris):
* - Changed data type of $ext from string to mixed. Now, $ext can be an array of possible extensions. Also, minor bug fix, in $ext and directories handling
* Changes from version 1.1 to 1.2 (2007/03/05 - peris):
* - Fixed recursion bug (Added $ext parameter to recurse call)
* Changes from version 1.0 to 1.1 (22/12/2005):
* - Added $ext parameter
*/
function eF_getDirContents($dir = false, $ext = false, $get_dir = true, $recurse = true)
{
    if ($dir) {
        $handle = opendir($dir);
    } else {
        $handle = opendir(getcwd());
    }
    
    $filelist = array();
    while (false !== ($file = readdir($handle))) {
        if ($file != "." AND $file != ".." AND $file != '.svn') {
            if (is_dir($dir.$file) && $recurse) {//echo "!$dir . $file@<br>";
                $temp = eF_getDirContents($dir.$file.'/', $ext, $get_dir);
                $get_dir ? $filelist[] = $dir.$file.'/' : $filelist[] = $file.'/';
                if (!$ext) {                      //It is put here for empty directories (when $ext is not specified), or, if $ext is specified, to not return directories
                    $filelist = array_merge($filelist, $temp);
                }
            } else {
                if ($ext) {
                    if (is_array($ext)) {
                        if (in_array(pathinfo($file, PATHINFO_EXTENSION), $ext)) {
                            $get_dir ? $filelist[] = $dir.$file : $filelist[] = $file;
                        }
                    } else {
                        if (pathinfo($file, PATHINFO_EXTENSION) == $ext) {
                            $get_dir ? $filelist[] = $dir.$file : $filelist[] = $file;
                        }
                    }
                } else {
                    $get_dir ? $filelist[] = $dir.$file : $filelist[] = $file;
                }
            }
        }
    }   
    return $filelist;
}

/**
* Recursively delete directory contents
*
* This function deletes all the contents of the designated folder, including subfolders, and the folder itself
* <br/>Example:
* <code>
* eF_deleteFolder('/tmp/useless_dir/');
* </code>
*
* @param string $folder The full pathname of the directory to be deleted
* @return bool true if everythin is ok.
* @see eF_getDirContents
* @todo return other than true
*/
function eF_deleteFolder($folder)
{
    $folder = $folder.'/';
    $filelist = eF_getDirContents($folder);
    for ($i = 0; $i < sizeof($filelist); $i++) {
        unlink($filelist[$i]);
    }
    
    $folders[] = $folder;
    
    for ($k = 0; $k < sizeof($folders); $k++) {
        $handle = opendir($folders[$k]);
        while (false !== ($file = readdir($handle))) {
            if ($file != "." AND $file != "..") {
                $folders[] = $folders[$k].'/'.$file;
            }
        }
        closedir($handle);
    }
    
    for ($k = sizeof($folders) - 1; $k >= 0; $k--) {
        rmdir($folders[$k]);
    }
    
    if (is_dir($folder)) {
        return false;
    } else {
        return true;
    }
}

/**
* Copies a complete folder
*
* This function copies a complete folder, with all its contents, into another location.
*
* @param string $src The source folder to copy
* @param string $dest The destination folder
* @return mixed True if everything is ok, or an array with failed file names
* @version 1.1 (2007/08/03 - peris)
* Changes from version 1.0 to 1.1:
* - If errors occur during file copy, the function returns an array with failed file names
* @version 1.0 (2007/07/30 - peris)
*/
function eF_copyFolder($src, $dest)
{
    if (!is_dir($src)) {
        return false;
    }
    $current_dir = getcwd();
    chdir($src);

    $filelist = eF_getDirContents();
    
    $destination_dir = $dest.basename($src);
    if (!is_dir($destination_dir)) {
        mkdir($destination_dir, 0755, true);
    }
    foreach ($filelist as $value) {
        if (strpos($value, '.svn') === false) {
            if (!is_dir($destination_dir.'/'.dirname($value))) {
                $temp = array($destination_dir.'/'.dirname($value));
                while (!is_dir(dirname(end($temp)))) {
                    $temp[] = dirname(end($temp));
                }
                for ($i = sizeof($temp) - 1; $i >= 0; $i--) {
                    mkdir($temp[$i], 0755, true);
                }
            }

            if (is_dir($value)) {                                                   //It is put here for empty directories
                if (strpos($value, '.svn') === false && !is_dir($destination_dir.'/'.$value)) {                             //
                    mkdir($destination_dir.'/'.$value, 0755, true);             
                }
            } else {
                if (!copy($value, $destination_dir.'/'.$value)) {
                    $failures[] = $destination_dir.'/'.$value;
                }
            }
        }
    }
        
    chdir($current_dir);   
    
    if (isset($failures)) {
        return $failures;
    } else {
        return true;
    }
}

/**
* Language file input
* 
* This function is used to parse a language file and return its contents. A language file
* consists of lins in the form:<br/>
* <code>
* define("_SOMETAG", "Some tag");
* </code>
* The function returns an array with two subarrays, one containing the tags and the other the corresponding tranlsations
*
* @param string $lang The language
* @return array The tags/translations array, or false if an error occured
* @version 2.0 (23/12/2005)
* Changes from version 1.0 to 2.0: 
* - Rewritten from scratch to comply with new structure
* 
*/
function eF_readLanguageFile($lang)
{
    $filename = G_ROOTPATH.'libraries/language/lang-'.$lang.'.php';
    if (is_file($filename)) {
        $contents = file($filename);
        foreach($contents as $line) {
            if (preg_match("/^define\(\"(.*)\",\s*\"(.*)\"\);/",  $line,  $regs)) {
                $variable[]    = $regs[1];
                $translation[] = $regs[2];
            }
        }
        return array($variable, $translation);        
    } else {
        return false;
    }
}

/**
* Appends strings at a language file
*
* This function is used to append new strings to the end of a language files to disk.
* It accepts two arguments: the first is the language to write a file for and the second one is 
* a string containing the line that will be appended. This function is used to add new tags
* in the language files. 
*
* @param string $lang The language to write
* @param array $trans The lines containing the language translations
* @version 1.0
* @todo must have a way to backup languages
* @todo get rid of global
* @todo It is not good, we should perform reindexing right away
* @todo filesystem
*/
function eF_appendLanguageFile($lang, $value)
{
    global $path;   

    $handle = fopen($path."language/lang-".$lang.".php", "a");
    fwrite($handle,"\n<?\n".$value."\n?>");
    fclose($handle);
}

/**
* Get the system temp directory
* 
* This function, copied from php manual comments on sys_get_temp_dir(), is used to emulate sys_get_temp_dir() 
* in systems that have PHP version earlier than 5.2.0
*
* @return string The system temp directory
* @version 1.0 (2007/07/30 - peris)
*/
function eF_sys_get_temp_dir() 
{
    if ( !function_exists('sys_get_temp_dir') )
    {
        // Based on http://www.phpit.net/
        // article/creating-zip-tar-archives-dynamically-php/2/
        function sys_get_temp_dir()
        {
            // Try to get from environment variable
            if ( !empty($_ENV['TMP']) )
            {
                return realpath( $_ENV['TMP'] );
            }
            else if ( !empty($_ENV['TMPDIR']) )
            {
                return realpath( $_ENV['TMPDIR'] );
            }
            else if ( !empty($_ENV['TEMP']) )
            {
                return realpath( $_ENV['TEMP'] );
            }

            // Detect by creating a temporary file
            else
            {
                // Try to use system's temporary directory
                // as random name shouldn't exist
                $temp_file = tempnam( md5(uniqid(rand(), TRUE)), '' );
                if ( $temp_file )
                {
                    $temp_dir = realpath( dirname($temp_file) );
                    unlink( $temp_file );
                    return $temp_dir;
                }
                else
                {
                    return FALSE;
                }
            }
        }
    } else {
        return sys_get_temp_dir();
    }
}

/**
* Handles any file uploading
*
* This function is used to simplify handling and error reporting when we are uploading files.
* <br/>Example:
* <code>
* $timestamp = time();
* list($ok, $upload_messages, $upload_messages_type, $filename) = eF_handleUploads("file_upload", "uploads/", $timestamp."_");  //This will upload all the files specified in the "file_upload" form field, move them to the "uploads" directory and append to their name the current timestamp. 
* //$uploaded_messages is an array with the error or succes message corresponding to each of the uploaded files 
* //$upload_messages_type is an array holding the correspnding message types
* //$filename is an array holding the uploaded files filenames 
* </code>
*
* @param string $field_name The upload file form field name
* @param string $target_dir The directory to put uploaded files into
* @param string $prefix A prefix that the uploaded files will be prepended with
* @param string $ext The extension that is only allowed for the files. If it is false, then we allow all the allowed_extensions
* @param string $target_filename The filename that the uploaded file will have (doesn't work if multiple files uploaded)
* @return array The results array.
* @todo handle better single uploads
* @version 0.9
*/
function eF_handleUploads($field_name, $target_dir, $prefix = '', $target_filename = '', $ext=false) {

    $ok = false;
    $upload_messages = array();
    
    if ($target_dir[mb_strlen($target_dir) - 1] != '/') {
        $target_dir = $target_dir.'/';
    }
    
    if ($prefix) {
        $prefix = $prefix.'_prefix_';
    }
    
    if ($target_filename && sizeof($_FILES[$field_name]['name']) > 1) {
        $target_filename = '';
    }
    
    $allowed_extensions    = eF_getTableData("configuration", "value", "name='allowed_extensions'");
    $disallowed_extensions = eF_getTableData("configuration", "value", "name='disallowed_extensions'");
    if (sizeof($allowed_extensions) == 0 || $allowed_extensions[0]['value'] == '') {
        unset ($allowed_extensions);
    }
    if (sizeof($disallowed_extensions) == 0 || $disallowed_extensions[0]['value'] == '') {
        unset ($disallowed_extensions);
    }    
    if ($ext == false){
        unset($ext);
    }
    
    //for ($count = 0; $count < sizeof($_FILES[$field_name]['name']); $count++) {
    foreach ($_FILES[$field_name]['name'] as $count => $value) {
        $message_type = 'failure';
        
        $file['tmp_name'] = $_FILES[$field_name]['tmp_name'][$count];
        $file['name']     = $_FILES[$field_name]['name'][$count];
        $file['error']    = $_FILES[$field_name]['error'][$count];
        $file['size']     = $_FILES[$field_name]['size'][$count];

        if ($file['error']) {
            switch ($file['error']) {
                case UPLOAD_ERR_INI_SIZE : 
                    $upload_messages[$count] = _THEFILE." ".($count + 1)." "._MUSTBESMALLERTHAN." ".ini_get('upload_max_filesize')."<br/>";
                    break;
                case UPLOAD_ERR_FORM_SIZE :
                    $upload_messages[$count] = _THEFILE." ".($count + 1)." "._MUSTBESMALLERTHAN." ".sprintf("%.0f", $_POST['MAX_FILE_SIZE']/1024)." "._KILOBYTES."<br/>";
                    break;
                case UPLOAD_ERR_PARTIAL :
                    $upload_messages[$count] = _PROBLEMUPLOADINGFILE." ".($count + 1);
                    break;
                case UPLOAD_ERR_NO_FILE :
                    //$upload_messages[$count] = _PROBLEMUPLOADINGFILE." ".($count + 1);
                    break;
                case UPLOAD_ERR_NO_TMP_DIR :
                    $upload_messages[$count] = _PROBLEMUPLOADINGFILE." ".($count + 1);
                    break;
                default:
                    $upload_messages[$count] = _PROBLEMUPLOADINGFILE." ".($count + 1);
                    break;
            }
        } else {
            $path_parts = pathinfo($file['name']);
            if ($file['size'] == 0) {
                $upload_messages[] = _FILEDOESNOTEXIST;
            } elseif ((isset($disallowed_extensions) && in_array($path_parts['extension'], explode(",", preg_replace("/\s+/", "", $disallowed_extensions[0]['value'])))) || $path_parts['extension'] == 'php') {           //php files NEVER upload!!!
                $upload_messages[$count] = _YOUCANNOTUPLOADFILESWITHTHISEXTENSION.': .'.$path_parts['extension'].' ('.$file['name'].')<br/>';
            } elseif (isset($allowed_extensions) && $path_parts && !in_array($path_parts['extension'], explode(",", preg_replace("/\s+/", "", $allowed_extensions[0]['value'])))) {
                $upload_messages[$count] = _YOUMAYONLYUPLOADFILESWITHEXTENSION.': '.$allowed_extensions[0]['value'].'<br/>';
            } elseif (!eF_checkParameter($file['name'], 'filename')) {
                $upload_messages[$count] = _INVALIDFILENAME;
            } else if ( isset($ext) && $path_parts && !in_array($path_parts['extension'], explode(",", preg_replace("/\s+/", "", $ext)))){
                $upload_messages[$count] = _YOUMAYONLYUPLOADFILESWITHEXTENSION.': '.$ext.'<br/>';
            } else {
                $new_name    = explode('.', $path_parts['basename']);                                                           //These 3 lines translate greek characters to greeklish characters
                if (!$target_filename) {
                    $new_name[0] = $prefix.$new_name[0];
                    //$new_name[0] = $prefix.iconv('UTF-8', 'ISO-8859-7', $new_name[0]);
                } else {
                    $new_name[0] = $prefix.$target_filename;
                }
                $new_name    = implode('.', $new_name);
                if (move_uploaded_file($file['tmp_name'], $target_dir.$new_name)) {
                    $upload_messages[$count]      = _THEFILE." ".($count + 1)." "._HASBEENSEND."<br/>";
                    $upload_messages_type[$count] = 'success';
                    $ok = true;
                } else {
                    $upload_messages[$count]      = _THEFILE." ".($count + 1)." "._COULDNOTBESEND."<br/>";
                    $upload_messages_type[$count] = 'failure';
                    $ok = false;
                }
            }
            $filename[$count] = $target_dir.$new_name;
        }
    }

    if ($ok) {
        return array($ok, $upload_messages, $upload_messages_type, $filename);
    } else {
        return array($ok, $upload_messages, $upload_messages_type, false);
    }
}


?>