Location: PHPKode > projects > phlyMail Lite > phlymail/handlers/files/getfromurl.php
<?php
/**
 * Add a file to the personal storage of a user by downloading it from the network
 * @package phlyMail Nahariya 4.0+ Default Branch
 * @subpackage Files handler
 * @copyright 2005-2010 phlyLabs, Berlin (http://phlylabs.de)
 * @version 4.0.6 2010-11-08
 */
// Only valid within phlyMail
if (!defined('_IN_PHM_')) die();
// We got to have the upload_tmp_dir set to something useful
if (!ini_get('upload_tmp_dir')) ini_set('upload_tmp_dir', $_PM_['path']['storage'].'/'.$_SESSION['phM_uid'].'/files/.tmp');

$uplIDName = 'DOWNLOAD_IDENTIFIER';
/**
 * Frontend requests download progress information
 * This requires either APCs implementation or the PECL extension uploadprogress,
 * you can easily get the PECL one with "pecl install uploadprogress", APC
 * is recommended for caching purposes
 */
if (isset($_REQUEST['uplInf']) && $_REQUEST['uplInf']) {
    $uid = $_SESSION['phM_uid'];
    session_write_close();
    $nfo = basename($_REQUEST['uplInf']);
    $info = array('time_start' => 0, 'time_last' => 0, 'speed_average' => 0
            ,'speed_last' => 0, 'bytes_uploaded' => 0, 'bytes_total' => 0
            ,'files_uploaded' => 0, 'est_sec' => 0);
    if (false !== ($ulinfo = @file_get_contents($_PM_['path']['storage'].'/'.$uid.'/files/.tmp/'.$nfo.'.dnl'))) {
        $ulinfo = explode(';', $ulinfo);
        if (is_array($ulinfo) && isset($ulinfo[3])) {
            $rate = ($ulinfo[0]-$ulinfo[1] != 0) ? $ulinfo[3]/($ulinfo[0]-$ulinfo[1]) : 0;
            $info = array('bytes_uploaded' => $ulinfo[3], 'bytes_total' => $ulinfo[2]
                    ,'time_start' => $ulinfo[0], 'time_last' => $ulinfo[1]
                    ,'est_sec' => ($rate != 0 && $ulinfo[3] != 0 && $ulinfo[2] != 0) ? ($ulinfo[2]-$ulinfo[3])/$rate : 0
                    ,'speed_average' => $rate
                    );
        }
    }
    $info['field'] = $nfo;
    sendJS(array('upload_stats' => $info), 1, 1);
}

if (!isset($_PM_files_iamincluded)) {
    $tpl = new fxl_cached_template($_PM_['path']['frontend'].'/templates/files.getfromurl.tpl', $_PM_['path']['tplcache'].'files.getfromurl.tpl');
    require_once($_PM_['path']['handler'].'/files/fs.php');
    $FS = new files_storage($_SESSION['phM_uid']);
    require_once($_PM_['path']['lib'].'/phm_mime_handler.php');
    $MIME = new phm_mime_handler($_PM_['path']['conf'].'/mime.map.wpop');
}
$defaultFolder = (isset($_SESSION['files_workfolder']) && $_SESSION['files_workfolder']) ? $_SESSION['files_workfolder'] : false;
$destfolder = (isset($_REQUEST['destfolder'])) ? intval($_REQUEST['destfolder']) : $defaultFolder;

if (isset($_REQUEST['destfolder'])) {
    $uploadname = basename($_REQUEST[$uplIDName]);
    $destinfo = $FS->get_folder_info($_REQUEST['destfolder']);
    $destpath = $_PM_['path']['storage'].'/'.$_SESSION['phM_uid'].'/files/'.$destinfo['folder_path'].'/'.$uploadname;
    $ulinfo = $_PM_['path']['storage'].'/'.$_SESSION['phM_uid'].'/files/.tmp/'.$uploadname.'.dnl';
    $stat = download($_REQUEST['file'], $destpath, $ulinfo, 1073741824);   // Replace max size with user's quota limit
    switch ($stat['error']) {
        case UPLOAD_ERR_INI_SIZE: $error = 'The file was too large.'; break;
        case UPLOAD_ERR_PARTIAL: $error = 'The file was only partially downloaded.'; break;
        case UPLOAD_ERR_NO_FILE: $error = 'Could not download the file'; break;
        case UPLOAD_ERR_CANT_WRITE: $error = 'Failed to write file to disk'; break;
    }
    list ($type) = $MIME->get_type_from_name($stat['name'], false);
    if (!$type) $type = ($stat['type']) ? $stat['type'] : 'application/octet-stream';
    $bicon = $MIME->get_icon_from_type($_PM_['path']['frontend'].'/filetypes/64', $type, array('png', 'jpg', 'jpeg', 'gif'));
    // Images get a nice thumbnail, additionally we gather some info for the indexer
    $ii = (substr($type, 0, 6) == 'image/') ? getimagesize($destpath) : array(0, 0, 0);
    // Only try creating the thumbnail with the correct GD support.
    // GIF got dropped a while ago, then reappeared again; JPEG or PNG might not be compiled in
    if ($ii[2] == 1 && !function_exists('imagecreatefromgif')) $ii[2] = 0;
    if ($ii[2] == 2 && !function_exists('imagecreatefromjpeg')) $ii[2] = 0;
    if ($ii[2] == 3 && !function_exists('imagecreatefrompng')) $ii[2] = 0;
    if ($ii[2] == 15 && !function_exists('imagecreatefromwbmp')) $ii[2] = 0;
    if (false !== $ii && $ii[2] > 0 && $ii[2] < 4) {
        $has_thumb = '0';
        if (function_exists('imagecreatetruecolor')) {
            $has_thumb = '1';
            $ti = $ii;
            if ($ti[0] > 190 || $ti[1] > 190) {
                $wf = $ti[0] / 190; // Calculate width factor
                $hf = $ti[1] / 190; // Calculate height factor
                if ($wf >= $hf) {
                    if ($wf > 1) {
                        $ti[0] /= $wf;
                        $ti[1] /= $wf;
                    }
                } else {
                    if ($hf > 1) {
                        $ti[0] /= $hf;
                        $ti[1] /= $hf;
                    }
                }
                $ti[0] = round($ti[0], 0);
                $ti[1] = round($ti[1], 0);
            }
            if ($ii[2] == 1) {
                $si = imagecreatefromgif($destpath);
            } elseif ($ii[2] == 2) {
                $si = imagecreatefromjpeg($destpath);
            } elseif ($ii[2] == 3) {
                $si = imagecreatefrompng($destpath);
            } elseif ($ii[2] == 15) {
                $si = imagecreatefromwbmp($destpath);
            }
            if (!$si) {
                $has_thumb = '0';
                $ti = array(0 => 0, 1 => 0);
            } else {
                $tn = imagecreatetruecolor($ti[0], $ti[1]);
                imagecopyresampled($tn, $si, 0, 0, 0, 0, $ti[0], $ti[1], $ii[0], $ii[1]);
                // Get the thumbnail and populate thumbinfo
                ob_start();
                if (imagetypes() & IMG_PNG) {
                    $thmime = 'image/png';
                    imagepng($tn, null);
                } elseif (imagetypes() & IMG_JPG) {
                    $thmime = 'image/jpeg';
                    imagejpeg($tn, null, 75);
                } elseif (imagetypes() & IMG_GIF) {
                    $thmime = 'image/gif';
                    imagegif($tn, null);
                }
                $thsize = ob_get_length();
                $thstream = ob_get_contents();
                ob_end_clean();
                imagedestroy($tn);
            }
        }
    } else {
        $ti = array(0 => 0, 1 => 0);
        $has_thumb = '0';
    }
    $friendlyname = basename(phm_stripslashes($stat['name']));
    $exists = $FS->item_exists($friendlyname, $destfolder);
    if ($exists) {
        $expos = strrpos($friendlyname, '.');
        // Yes, we mean "Not found" AND "on position 0"!
        if (!$expos) {
            $basename = $friendlyname;
            $ext = '';
        } else {
            $basename = substr($friendlyname, 0, $expos);
            $ext = substr($friendlyname, $expos);
        }
        $adder = 1;
        while (true) {
            $match = $FS->item_exists($basename.' ('.$adder.')'.$ext, $destfolder);
            if (!$match) {
                $friendlyname = $basename.' ('.$adder.')'.$ext;
                break;
            }
            ++$adder;
        }
    }
    $FS->file_item(array
            ('folder_id' => $destfolder
            ,'filed' => true
            ,'filename' => $uploadname
            ,'friendlyname' => $friendlyname
            ,'type' => $type
            ,'size' => $stat['size']
            ,'img_w' => $ii[0]
            ,'img_h' => $ii[1]
            ,'thumb' => serialize(array
                    ('has' => $has_thumb, 'w' => $ti[0], 'h' => $ti[1]
                    ,'mime' => ($has_thumb) ? $thmime : ''
                    ,'size' => ($has_thumb) ? $thsize : 0
                    ,'stream' => ($has_thumb) ? $thstream : ''
                    ))
            ));
    if (isset($_PM_files_iamincluded)) return;
    $tpl->assign_block('onupload');
    $tpl->assign(array
            ('name' => $stat['name']
            ,'big_icon' => $_PM_['path']['frontend'].'/filetypes/64/'.$bicon
            ,'mimetype' => $stat['type']
            ,'opener' => (isset($_REQUEST['opener'])) ? $_REQUEST['opener'] : false
            ));
} else {
    if (isset($_PM_files_iamincluded)) return;
    $tpl->assign_block('default');
}
if (isset($_PM_files_iamincluded)) return;

$FS->init_folders();
$t_inb = $tpl->get_block('destfolder');
foreach ($FS->read_folders_flat() as $id => $data) {
    $lvl_space = ($data['level'] > 0) ? str_repeat('&nbsp;', $data['level'] * 2) : '';
    $t_inb->assign(array
            ('id' => (!$data['has_items'])
                    ? '" style="color:darkgray;" disabled="disabled'
                    : $id.($id == $defaultFolder ? '" selected="selected' : '')
            ,'name' => $lvl_space . phm_entities($data['foldername'])
            ));
    $tpl->assign('destfolder', $t_inb);
    $t_inb->clear();
}
$passthru = give_passthrough(1);
$tpl->assign(array
        ('action' => htmlspecialchars(PHP_SELF.'?load=getfromurl&handler=files&'.$passthru)
        ,'opener' => (isset($_REQUEST['opener'])) ? phm_entities($_REQUEST['opener']) : false
        ,'msg_select' => $WP_msg['EnterURL']
        ,'msg_upload' => $WP_msg['Upload']
        ,'about_done' => $WP_msg['UploadDone']
        ,'msg_filetofolder' => $WP_msg['FldrBrwsSelect']
        ,'leg_enterurl' => $WP_msg['DownloadFromURL']
        ,'leg_localfolder' => $WP_msg['LegLocalFolder']
        ,'UL_ID' => uniqid($_SESSION['phM_uid'], true)
        ,'UL_ID_NAME' => $uplIDName
        ,'upload_progress_url_js' => PHP_SELF.'?load=getfromurl&handler=files&'.$passthru.'&uplInf='
        ));
/**
 * The internal function to download a file from a URL, given that allow_url_fopen is allowed
 *
 * @param string $file_source  a HTTP or FTP URI. No other means are supported right now due to
 *      security reasons (a malicious person could try to "download" local files
 * @param string $file_target internal target file
 * @param string $uploadinfo Where to put and how to name the donwload info for APC upload progress
 * @param string $maxsize maximum file size (not checked for right now)
 * @return array
 * 'error' int corresponding to the UPLOAD_ERR_xxx constants
 * 'size'  int  size in bytes actually downloaded
 * 'name'  string  file name as deliviered by the server
 * 'type' string  MIME type as delivered by the server
 */
function download($file_source, $file_target, $uploadinfo, $maxsize = 1073741824)
{
    $start = time();
    $return = array('error' => UPLOAD_ERR_NO_FILE, 'size' => 0, 'name' => '', 'type' => 'application/octet-stream');
    $allowedSchemes = array('http', 'https', 'ftp', 'ftps');
    $file_source = str_replace(' ', '%20', html_entity_decode($file_source)); // fix url format
    $state = ($uriparts = @parse_url($file_source));
    if (!$state) return $return;
    if (empty($uriparts)) return $return;
    if (!in_array($uriparts['scheme'], $allowedSchemes)) return $return;
    if (file_exists($file_target)) chmod($file_target, $GLOBALS['_PM_']['core']['file_umask']);
    if (($rh = fopen($file_source, 'rb')) === false) {
        $return['error'] = UPLOAD_ERR_NO_FILE;
        return $return;
    }
    if (($wh = fopen($file_target, 'wb')) === false) {
        $return['error'] = UPLOAD_ERR_CANT_WRITE;
        return $return;
    }
    $headers = stream_get_meta_data($rh);
    foreach ($headers['wrapper_data'] as $head) {
        if (strtolower(substr($head, 0, 13)) == 'content-type:') $return['type'] = trim(strtolower(substr($head, 13)));
        if (strtolower(substr($head, 0, 15)) == 'content-length:') $return['size'] = trim(strtolower(substr($head, 15)));
        if ($return['name'] == '' && preg_match('!name=("?)(.*)\1!i', $head, $found)) $return['name'] = $found[2];
    }
    // Set a default name
    if ($return['name'] == '' && isset($uriparts['path'])) $return['name'] = basename(urldecode($uriparts['path']));
    // error handling
    if ($return['size'] > 0 && $return['size'] > $maxsize) {
        fclose($rh);
        fclose($wh);
        $return['error'] = UPLOAD_ERR_INI_SIZE;
        return $return;
    }
    while (!feof($rh)) {
        // unable to write to file, possibly because the harddrive has filled up
        if (fwrite($wh, fread($rh, 16384)) === false) {
            fclose($rh);
            fclose($wh);
            $return['error'] = UPLOAD_ERR_PARTIAL;
            return $return;
        }
        $stat = fstat($wh);
        if ($stat['size'] >= $maxsize) {
            fclose($rh);
            fclose($wh);
            $return['error'] = UPLOAD_ERR_PARTIAL;
            return $return;
        }
        clearstatcache();
        file_put_contents($uploadinfo.'.dnl', $start.';'.time().';'.$return['size'].';'.$stat['size']);
    }
    // Finished without errors
    fclose($rh);
    fclose($wh);
    unlink($uploadinfo);
    $return['error'] = UPLOAD_ERR_OK;
    return $return;
}
?>
Return current item: phlyMail Lite