e107inc/e107

View on GitHub
e107_plugins/download/request.php

Summary

Maintainability
A
2 hrs
Test Coverage
F
12%
<?php
if (!defined('e107_INIT'))
{
    require_once(__DIR__.'/../../class2.php');
}

e107::lan('download','download');

class download_request
{

    static function request()
    {

        $log = e107::getLog();
        $id = false;

        $sql = e107::getDb();
        $tp = e107::getParser();
        $pref = e107::pref();

        if(!is_numeric(e_QUERY) && empty($_GET['id']))
        {
            if($sql->select('download', 'download_id', "download_url='" . $tp->toDB(e_QUERY) . "'"))
            {
                $row = $sql->fetch();
                $type = 'file';
                $id = $row['download_id'];
            }
            elseif((strpos(e_QUERY, "http://") === 0) || (strpos(e_QUERY, "ftp://") === 0) || (strpos(e_QUERY, "https://") === 0))
            {
                header("location: " . e_QUERY);
                exit();
            }
            elseif(file_exists(e_DOWNLOAD . e_QUERY) && !is_dir(e_DOWNLOAD . e_QUERY))        // 1 - should we allow this?
            {
                e107::getFile()->send(e_DOWNLOAD . e_QUERY);
                exit();
            }
        }


        if(strpos(e_QUERY, "mirror") !== false)
        {    // Download from mirror
            list($action, $download_id, $mirror_id) = explode(".", e_QUERY);
            $download_id = intval($download_id);
            $mirror_id = intval($mirror_id);
            $qry = "SELECT d.*, dc.download_category_class FROM #download as d LEFT JOIN #download_category AS dc ON dc.download_category_id = d.download_category WHERE d.download_id = {$download_id}";
            if($sql->gen($qry))
            {
                $row = $sql->fetch();
                extract($row);
                if(check_class($row['download_category_class']) && check_class($row['download_class']))
                {
                    if(!empty($pref['download_limits']) && $row['download_active'] == 1)
                    {
                        self::check_download_limits();
                    }
                    $mirrorList = explode(chr(1), $row['download_mirror']);
                    $mstr = "";
                    foreach($mirrorList as $mirror)
                    {
                        if($mirror)
                        {
                            $tmp = explode(",", $mirror);
                            $mid = intval($tmp[0]);
                            $address = $tmp[1];
                            $requests = $tmp[2];
                            if($tmp[0] == $mirror_id)
                            {
                                $gaddress = trim($address);
                                $requests++;
                            }
                            $mstr .= $mid . "," . $address . "," . $requests . chr(1);
                        }
                    }
                    $sql->update("download", "download_requested = download_requested + 1, download_mirror = '{$mstr}' WHERE download_id = '" . intval($download_id) . "'");
                    $sql->update("download_mirror", "mirror_count = mirror_count + 1 WHERE mirror_id = '" . intval($mirror_id) . "'");

                    if(!empty($gaddress))
                    {
                        header("Location: " . self::decorate_download_location($gaddress));
                    }
                    exit();
                }

                $goUrl = e107::url('download', 'index', null, array('query' => array('action' => 'error', 'id' => 1))); // ."?action=error&id=1";
                e107::redirect($goUrl);
                //header("Location: ".e_BASE."download.php?error.{$download_id}.1");
                exit;
            }
        }

        $tmp = explode(".", e_QUERY);
        if(empty($tmp[1]) || strpos(e_QUERY, "pub_") !== false)
        {
            $id = intval($tmp[0]);
            $type = "file";
        }
        else
        {
            $table = preg_replace("#\W#", "", $tp->toDB($tmp[0], true));
            $id = intval($tmp[1]);
            $type = "image";
        }

        if(vartrue($_GET['id'])) // SEF URL
        {
            $id = intval($_GET['id']);
            $type = 'file';
        }


        if(preg_match("#.*\.[a-z,A-Z]{3,4}#", e_QUERY))
        {
            if(strpos(e_QUERY, "pub_") !== false)
            {
                $bid = str_replace("pub_", "", e_QUERY);
                if(file_exists(e_UPLOAD . $bid))
                {
                    e107::getFile()->send(e_UPLOAD . $bid);
                    exit();
                }
                $log->addError("Line" . __LINE__ . ": Couldn't find " . e_UPLOAD . $bid . "");
            }
            if(file_exists(e_DOWNLOAD . e_QUERY))
            {
                e107::getFile()->send(e_DOWNLOAD . e_QUERY);
                exit();
            }
            $log->addError("Line" . __LINE__ . ": Couldn't find " . e_DOWNLOAD . e_QUERY);
            $log->toFile('download_requests', 'Download Requests', true); // Create a log file and add the log messages
            require_once(HEADERF);
            e107::getRender()->tablerender(LAN_ERROR, "<div style='text-align:center'>" . LAN_FILE_NOT_FOUND . "\n<br /><br />\n<a href='javascript:history.back(1)'>" . LAN_BACK . "</a></div>");
            require_once(FOOTERF);
            exit();
        }

        if($type == "file")
        {
            $qry = "SELECT d.*, dc.download_category_class FROM #download as d LEFT JOIN #download_category AS dc ON dc.download_category_id = d.download_category WHERE d.download_id = {$id}";
            if($sql->gen($qry))
            {
                $row = $sql->fetch();

                $row['download_url'] = $tp->replaceConstants($row['download_url']); // must be relative file-path.

                if(check_class($row['download_category_class']) && check_class($row['download_class']))
                {
                    if($row['download_active'] == 0) // Inactive download - don't allow
                    {
                        require_once(HEADERF);
                        $search = array("[", "]");
                        $replace = array("<a href='" . e_HTTP . "download.php'>", "</a>");

                        e107::getRender()->tablerender(LAN_ERROR, "<div class='alert alert-warning' style='text-align:center'>" . str_replace($search, $replace, LAN_dl_78) . '</div>');
                        require_once(FOOTERF);
                        exit();
                    }

                    if($pref['download_limits'] && $row['download_active'] == 1)
                    {
                        self::check_download_limits();
                    }
                    extract($row);
                    if($row['download_mirror'])
                    {
                        $array = explode(chr(1), $row['download_mirror']);
                        $c = (count($array) - 1);
                        for($i = 1; $i < $c; $i++)
                        {
                            $d = mt_rand(0, $i);
                            $tmp = $array[$i];
                            $array[$i] = $array[$d];
                            $array[$d] = $tmp;
                        }
                        $tmp = explode(",", $array[0]);
                        $mirror_id = $tmp[0];
                        $mstr = "";
                        foreach($array as $mirror)
                        {
                            if($mirror)
                            {
                                $tmp = explode(",", $mirror);
                                $mid = $tmp[0];
                                $address = $tmp[1];
                                $requests = $tmp[2];
                                if($tmp[0] == $mirror_id)
                                {
                                    $gaddress = trim($address);
                                    $requests++;
                                }
                                $mstr .= $mid . "," . $address . "," . $requests . chr(1);
                            }
                        }
                        $sql->update("download", "download_requested = download_requested + 1, download_mirror = '{$mstr}' WHERE download_id = '" . intval($download_id) . "'");
                        $sql->update("download_mirror", "mirror_count = mirror_count + 1 WHERE mirror_id = '" . intval($mirror_id) . "'");
                        if(!empty($gaddress))
                        {
                            header("Location: " . self::decorate_download_location($gaddress));
                        }
                        exit();
                    }

                    // increment download count
                    $sql->update("download", "download_requested = download_requested + 1 WHERE download_id = '{$id}'");
                    $user_id = USER ? USERID : 0;
                    $ip = e107::getIPHandler()->getIP(false);
                    $request_data = "'0', '{$user_id}', '{$ip}', '{$id}', '" . time() . "'";
                    //add request info to db
                    $sql->insert("download_requests", $request_data);
                    //    if (preg_match("/Binary\s(.*?)\/.*/", $download_url, $result))
                    //    {
                    //        $bid = $result[1];
                    ///        $result = @mysql_query("SELECT * FROM ".MPREFIX."rbinary WHERE binary_id = '{$bid}'");
                    //        $binary_data = @mysql_result($result, 0, "binary_data");
                    //        $binary_filetype = @mysql_result($result, 0, "binary_filetype");
                    //        $binary_name = @mysql_result($result, 0, "binary_name");
                    //        header("Content-type: {$binary_filetype}");
                    //        header("Content-length: {$download_filesize}");
                    //        header("Content-Disposition: attachment; filename={$binary_name}");
                    //        header("Content-Description: PHP Generated Data");
                    //        echo $binary_data;
                    //        exit();
                    //    }
                    if(strpos($row['download_url'], "http://") !== false || strpos($row['download_url'], "ftp://") !== false || strpos($row['download_url'], "https://") !== false)
                    {
                        $download_url = e107::getParser()->parseTemplate($row['download_url']); // support for shortcode-driven dynamic URLS.
                        e107::redirect(self::decorate_download_location($download_url));
                        // header("Location: {$download_url}");
                        exit();
                    }
                    else
                    {
                        if(file_exists(e_DOWNLOAD . $row['download_url']))
                        {
                            e107::getFile()->send(e_DOWNLOAD . $row['download_url']);
                            exit();
                        }
                        elseif(file_exists($row['download_url']))
                        {
                            e107::getFile()->send($row['download_url']);
                            exit();
                        }
                        elseif(file_exists(e_UPLOAD . $row['download_url']))
                        {
                            e107::getFile()->send(e_UPLOAD . $row['download_url']);
                            exit();
                        }
                        $log->addError("Couldn't find " . e_DOWNLOAD . $row['download_url'] . " or " . $row['download_url'] . " or " . e_UPLOAD . $row['download_url']);
                        $log->toFile('download_requests', 'Download Requests', true); // Create a log file and add the log messages
                    }
                }
                else
                {    // Download Access Denied.
                    if((!strpos($pref['download_denied'], ".php") &&
                        !strpos($pref['download_denied'], ".htm") &&
                        !strpos($pref['download_denied'], ".html") &&
                        !strpos($pref['download_denied'], ".shtml") ||
                        (strpos($pref['download_denied'], "signup.php") && USER == true)
                    ))
                    {
                        //    $goUrl = e107::getUrl()->create('download/index')."?action=error&id=1";
                        $goUrl = e107::url('download', 'index', null, array('query' => array('action' => 'error', 'id' => 1)));
                        e107::redirect($goUrl);
                        return;
                    }
                    else
                    {
                        e107::redirect(trim($pref['download_denied']));
                        return;
                    }
                }
            }
            //else if(strstr(e_QUERY, "pub_"))
    //    {
            /* check to see if public upload and not in download table ... */
            /*$bid = str_replace("pub_", "", e_QUERY);
            if($result = @mysql_query("SELECT * FROM ".MPREFIX."rbinary WHERE binary_id = '$bid' "))
            {
                $binary_data = @mysql_result($result, 0, "binary_data");
                $binary_filetype = @mysql_result($result, 0, "binary_filetype");
                $binary_name = @mysql_result($result, 0, "binary_name");
                header("Content-type: {$binary_filetype}");
                header("Content-length: {$download_filesize}");
                header("Content-Disposition: attachment; filename={$binary_name}");
                header("Content-Description: PHP Generated Data");
                echo $binary_data;
                exit();
            }*/
    //    }


            $log->addError("Line" . __LINE__ . ": Couldn't find " . e_DOWNLOAD . e_QUERY);
            $log->toFile('download_requests', 'Download Requests', true); // Create a log file and add the log messages
            require_once(HEADERF);
            e107::getRender()->tablerender(LAN_ERROR, "<div style='text-align:center'>" . LAN_FILE_NOT_FOUND . "<br /><br /><a href='javascript:history.back(1)'>" . LAN_BACK . "</a></div>");
            require_once(FOOTERF);
            return;
        }

        $sql->select($table, "*", "{$table}_id = '{$id}'");
        $row = $sql->fetch();
        extract($row);
        $image = ($table == "upload" ? $row['upload_ss'] : $row['download_image']);
    //if (preg_match("/Binary\s(.*?)\/.*/", $image, $result))
    //{
        /*    $bid = $result[1];
            $result = @mysql_query("SELECT * FROM ".MPREFIX."rbinary WHERE binary_id = '{$bid}'");
            $binary_data = @mysql_result($result, 0, "binary_data");
            $binary_filetype = @mysql_result($result, 0, "binary_filetype");
            $binary_name = @mysql_result($result, 0, "binary_name");
            header("Content-type: {$binary_filetype}");
            header("Content-Disposition: inline; filename={$binary_name}");
            echo $binary_data;
            exit();*/

    //}


    // $image = ($table == "upload" ? $upload_ss : $download_image);

        if(strpos($image, "http") !== false)
        {
            e107::redirect($image);
            exit();
        }
        else
        {
            if($table == "download")
            {
                require_once(HEADERF);
                $imagecaption = ''; // TODO ?name or text Screenshot

                if(file_exists(e_FILE . "download/{$image}"))
                {
                    $disp = "<div style='text-align:center'><img class='img-responsive img-fluid' src='" . e_FILE_ABS . "download/{$image}' alt='' /></div>";
                }
                elseif(file_exists(e_FILE . "downloadimages/{$image}"))
                {
                    $disp = "<div style='text-align:center'><img class='img-responsive img-fluid' src='" . e_FILE_ABS . "downloadimages/{$image}' alt='' /></div>";
                }
                else
                {
                    $image = $tp->replaceConstants($image, 'abs');
                    $disp = "<div style='text-align:center'><img class='img-responsive img-fluid' src='" . $image . "' alt='' /></div>";
                }

                $disp .= "<br /><div style='text-align:center'><a href='javascript:history.back(1)'>" . LAN_BACK . "</a></div>";

                e107::getRender()->tablerender($imagecaption, $disp);

                require_once(FOOTERF);
            }
            else
            {
                if(is_file(e_UPLOAD . $image))
                {
                    echo "<img src='" . e_UPLOAD . $image . "' alt='' />";
                }
                elseif(is_file(e_FILE . "downloadimages/{$image}"))
                {
                    echo "<img src='" . e_FILE_ABS . "downloadimages/{$image}' alt='' />";
                }
                else
                {
                    require_once(HEADERF);
                    e107::getRender()->tablerender(LAN_ERROR, "<div style='text-align:center'>" . LAN_FILE_NOT_FOUND . "<br /><br /><a href='javascript:history.back(1)'>" . LAN_BACK . "</a></div>");
                    require_once(FOOTERF);
                }

                return;
            }
        }
    }


    private static function check_download_limits()
    {
        global $HEADER;
        $sql = e107::getDb();
        $pref = e107::getPref();

        // Check download count limits
        $qry = "SELECT gen_intdata, gen_chardata, (gen_intdata/gen_chardata) as count_perday FROM #generic WHERE gen_type = 'download_limit' AND gen_datestamp IN (".USERCLASS_LIST.") AND (gen_chardata >= 0 AND gen_intdata >= 0) ORDER BY count_perday DESC";
        if($sql->gen($qry))
        {
            $limits = $sql->fetch();
            $cutoff = time() - (86400 * $limits['gen_chardata']);
            if(USER)
            {
                $where = "dr.download_request_datestamp > {$cutoff} AND dr.download_request_userid = ".USERID;
            }
            else
            {
                $ip = e107::getIPHandler()->getIP();
                $where = "dr.download_request_datestamp > {$cutoff} AND dr.download_request_ip = '{$ip}'";
            }
            $qry = "SELECT COUNT(d.download_id) as count FROM #download_requests as dr LEFT JOIN #download as d ON dr.download_request_download_id = d.download_id AND d.download_active = 1 WHERE {$where} GROUP by dr.download_request_userid";
            if($sql->gen($qry))
            {
                $row = $sql->fetch();
                if($row['count'] >= $limits['gen_intdata'])
                {
                    // Exceeded download count limit
                //    $goUrl = e107::getUrl()->create('download/index')."?action=error&id=2";
                    $goUrl = e107::url('download', 'index', null, array('query'=>array('action'=>'error','id'=>2)));
                    e107::redirect($goUrl);
                 //     e107::redirect(e_BASE."download.php?error.{$cutoff}.2");
                    /* require_once(HEADERF);
                    $ns->tablerender(LAN_ERROR, LAN_dl_62);
                    require(FOOTERF);  */
                    exit();
                }
            }
        }
        // Check download bandwidth limits
        $qry = "SELECT gen_user_id, gen_ip, (gen_user_id/gen_ip) as bw_perday FROM #generic WHERE gen_type='download_limit' AND gen_datestamp IN (".USERCLASS_LIST.") AND (gen_user_id >= 0 AND gen_ip >= 0) ORDER BY bw_perday DESC";
        if($sql->gen($qry))
        {
            $limit = $sql->fetch();
            $cutoff = time() - (86400*$limit['gen_ip']);
            if(USER)
            {
                $where = "dr.download_request_datestamp > {$cutoff} AND dr.download_request_userid = ".USERID;
            }
            else
            {
                $ip = e107::getIPHandler()->getIP();
                $where = "dr.download_request_datestamp > {$cutoff} AND dr.download_request_ip = '{$ip}'";
            }
            $qry = "SELECT SUM(d.download_filesize) as total_bw FROM #download_requests as dr LEFT JOIN #download as d ON dr.download_request_download_id = d.download_id AND d.download_active = 1 WHERE {$where} GROUP by dr.download_request_userid";
            if($sql->gen($qry))
            {
                $row = $sql->fetch();

                if($row['total_bw'] / 1024 > $limit['gen_user_id'])
                {    //Exceed bandwith limit
                //    $goUrl = e107::getUrl()->create('download/index')."?action=error&id=2";
                    $goUrl = e107::url('download', 'index', null, array('query'=>array('action'=>'error','id'=>2)));
                     e107::redirect($goUrl);
                 // e107::redirect(e_BASE."download.php?error.{$cutoff}.2");
                    /* require(HEADERF);
                    $ns->tablerender(LAN_ERROR, LAN_dl_62);
                    require(FOOTERF); */
                    exit();
                }
            }
        }
    }

    private static function decorate_download_location($url)
    {
        $pref = e107::getPref();

        if (varset($pref['download_security_mode']) !== 'nginx-secure_link_md5')
        {
            return $url;
        }

        require_once(__DIR__."/handlers/NginxSecureLinkMd5Decorator.php");
        $decorator = new NginxSecureLinkMd5Decorator($url, $pref);
        return $decorator->decorate();
    }

}


download_request::request();