<?php

require_once 'classes/SnapinPlugin.php';

class PluginPhpsysinfo extends SnapinPlugin
{
    function getVariables()
    {
        $variables = array(
            /*T*/'Plugin Name'/*/T*/       => array(
                'type'        => 'hidden',
                'description' => /*T*/''/*/T*/,
                'value'       => 'Server Info',
            ),
            /*T*/'Viewable in the Public Section'/*/T*/   => array(
                'type'        => 'yesno',
                'description' => /*T*/''/*/T*/,
                'value'       => false,
            ),
        );

        return $variables;
    }

    function view()
    {
        if (isset($_GET['pluginaction'])) {
            switch ($_GET['pluginaction']) {
                case 'showserver':
                    $this->_showServer();
                    break;
            }
        }

        $this->_showServerDropDown();

        $this->tpl->parse('output', 'serverstats_template');
        return $this->tpl->fetch('output');
    }

    function getDashboardData($statsurl)
    {
        $xml = $this->_getXML($statsurl);
        return array(
            'loadAverages'      => $this->_getLoadAverages($xml),
            'uptime'            => $this->_getUptime($xml),
            'memoryUsedPercent' => $this->_getMemUsedPercent($xml),
            'memoryCached'      => $this->_getCachedPercent($xml),
            'mounts'            => $this->_getMounts($xml),
        );
    }

    function getPublicOutput()
    {
        require_once 'modules/admin/models/ServerGateway.php';
        $serverGateway = new ServerGateway();
        $result = $serverGateway->getStatsUrlDBIT($this->user, true);
        $output = '';
        while ($row = $result->fetch()) {
            $xml = $this->_getXML($row['statsurl']);
            $output .= '<li><h4 style="font-weight:bold">Server '.$row['name'].'</h4><p><b>Load Average: </b>'.$this->_getLoadAverages($xml).'<br /><b>Uptime: </b>'.$this->_getUptime($xml).'</p></li>';
        }

        if (!$output) {
            return false;
        }

        return "<ul>$output</ul>";
    }

    function _showServerDropDown()
    {
        // Get list of servers
        if ($this->user->isAdmin()) {
            $sql = "SELECT s.id, s.name FROM server s WHERE statsurl != '' ORDER BY s.name";
            $result = $this->db->query($sql);
        } else {
            $sql = "SELECT DISTINCT(s.id), s.name FROM server s, domains d "
                  ."WHERE d.serverid = s.id AND s.statsurl != '' AND s.statsviewable = 1 AND d.CustomerID = ? ORDER BY s.name";
            $result = $this->db->query($sql, $this->user->getId());
        }

        if (NE_Lib::isPublicDir()) {
            $this->tpl->define(array('serverstats_template' => '../../plugins/snapins/phpsysinfo/PublicSection_phpsysinfo.tpl'));
        } else {
            $this->tpl->define(array('serverstats_template' => '../../plugins/snapins/phpsysinfo/phpsysinfo.tpl'));
        }
        
        $this->tpl->define_dynamic('serverstats', 'serverstats_template');

        $this->tpl->setKey(array(
            'SYSINFO_FUSE'          => $this->user->isAdmin()? 'admin': 'clients',
            'SYSINFO_ACTION'        => $this->user->isAdmin()? 'Snapins' : 'ShowSnapinsCustomer',
            'SYSINFO_POPUPHELP1'    => NE_Lib::returnPopupString($this->user->lang('To add a server, set the \'Status URL\' field in the server\'s configuration screen').'.', $this->settings),
        ));

        $this->tpl->setKey(array(
            'LANUAGE_SELECTSERVER' => $this->user->lang('Select Server')
        ));

        while (list($serverid, $servername) = $result->fetch())
        {

            if(isset($_GET['serverid']) && $_GET['serverid'] == $serverid) {
                $selected = "SELECTED";
            }else{
                $selected = "";
            }

            $this->tpl->setKey(array('SYSINFO_SELECTED' => $selected));
            $this->tpl->setKey(array(
                'SYSINFO_SERVER' => $serverid,
                'SYSINFO_SERVERNAME'   => $servername,
            ));
            $this->tpl->subst('trash', '.servers');
        }
    }

    function _showServer()
    {
        if ($this->user->isAdmin()) {
            $sql = "SELECT s.statsurl, s.name FROM server s WHERE s.id=?";
            $result = $this->db->query($sql,$_GET['serverid']);
        } else {
            $sql = "SELECT s.statsurl, s.name FROM server s, domains d "
                  ."WHERE d.serverid=s.id AND s.statsviewable=1 AND s.id=? AND d.CustomerID=?";
            $result = $this->db->query($sql,$_GET['serverid'], $this->user->getId());
        }
        list($statsurl, $servername) = $result->fetch();


        if (NE_Lib::isPublicDir()) {
            $this->tpl->define(array('serverstatspage_template' => '../../plugins/snapins/phpsysinfo/PublicSection_phpsysinfo_serverinfo.tpl'));
        } else {
            $this->tpl->define(array('serverstatspage_template' => '../../plugins/snapins/phpsysinfo/phpsysinfo_serverinfo.tpl'));
        }
        
        $this->tpl->define_dynamic('serverstatspage', 'serverstatspage_template');

        $xml = $this->_getXML($statsurl);

        $this->_SetVitals($xml);
        $this->_SetHardware($xml);
        $this->_NetworkUsage($xml);
        $this->_MemoryUsage($xml);
        $this->_FileSystem($xml);

        $this->tpl->parse('inneroutput', 'serverstatspage_template');

        $this->tpl->setKey(array(
            'SYSINFO_SERVERSTATS' => $this->tpl->fetch('inneroutput')
        ));

    }

    function _getXML($statsurl)
    {
        require_once 'newedge/classes/XmlFunctions.php';
        require_once 'newedge/classes/NE_Network.php';

        $xmldata = NE_Network::curlRequest($this->settings, $statsurl, false, false, true, true);

        //need to validate XML before we do anything so that we do not
        //get unexpected errors when using this xmlize function
        $xml = XmlFunctions::xmlize($xmldata,1);

        return $xml;
    }

    function _MemoryUsage($xml)
    {
        //Getting Physical Memory
        //we get these in kilobytes so we convert to byte before passing to this function
        $memfree = $this->_ConvertByte(floatval($xml["phpsysinfo"]["#"]["Memory"][0]["#"]["Free"][0]["#"])*1024,"");
        $memtotal = $this->_ConvertByte(floatval($xml["phpsysinfo"]["#"]["Memory"][0]["#"]["Total"][0]["#"])*1024,"");

        //Get Kernal + Application
        //we get these in kilobytes so we convert to byte before passing to this function
        $kernused = $this->_ConvertByte(floatval($xml["phpsysinfo"]["#"]["Memory"][0]["#"]["App"][0]["#"])*1024,"");
        $kernpercent = $xml["phpsysinfo"]["#"]["Memory"][0]["#"]["AppPercent"][0]["#"];

        //Get Buffers
        //we get these in kilobytes so we convert to byte before passing to this function
        $buffused = $this->_ConvertByte(floatval($xml["phpsysinfo"]["#"]["Memory"][0]["#"]["Buffers"][0]["#"])*1024,"");
        $buffpercent = $xml["phpsysinfo"]["#"]["Memory"][0]["#"]["BuffersPercent"][0]["#"];

        //Get Cached
        //we get these in kilobytes so we convert to byte before passing to this function
        $cachedused = $this->_ConvertByte(floatval($xml["phpsysinfo"]["#"]["Memory"][0]["#"]["Cached"][0]["#"])*1024,"");
        
        // Get Disk Swap
        //we get these in kilobytes so we convert to byte before passing to this function
        $swapused = $this->_ConvertByte(floatval($xml["phpsysinfo"]["#"]["Swap"][0]["#"]["Used"][0]["#"])*1024,"");
        $swapfree = $this->_ConvertByte(floatval($xml["phpsysinfo"]["#"]["Swap"][0]["#"]["Free"][0]["#"])*1024,"");
        $swaptotal = $this->_ConvertByte(floatval($xml["phpsysinfo"]["#"]["Swap"][0]["#"]["Total"][0]["#"])*1024,"");
        $swappercent = $xml["phpsysinfo"]["#"]["Swap"][0]["#"]["Percent"][0]["#"];

        //Set Vitals
        $this->tpl->setKey(array(
            'SYSINFO_MEMFREE'       => $memfree,
            'SYSINFO_MEMUSED'       => $this->_getMemUsed($xml),
            'SYSINFO_MEMTOTAL'      => $memtotal,
            'SYSINFO_MEMPERCENT'    => $this->bar($this->_getMemUsedPercent($xml),100),
            'SYSINFO_KERNUSED'      => $kernused,
            'SYSINFO_KERNPERCENT'   => $this->bar($kernpercent,100),
            'SYSINFO_BUFFUSED'      => $buffused,
            'SYSINFO_BUFFPERCENT'   => $this->bar($buffpercent,100),
            'SYSINFO_CACHUSED'      => $cachedused,
            'SYSINFO_CACHPERCENT'   => $this->bar($this->_getCachedPercent($xml),100),
            'SYSINFO_SWAPFREE'      => $swapfree,
            'SYSINFO_SWAPUSED'      => $swapused,
            'SYSINFO_SWAPTOTAL'     => $swaptotal,
            'SYSINFO_SWAPPERCENT'   => $this->bar($swappercent,100),
        ));
    }

    function _getMemUsed(&$xml)
    {
        return $this->_ConvertByte(floatval($xml["phpsysinfo"]["#"]["Memory"][0]["#"]["Used"][0]["#"])*1024,"");
    }

    function _getMemUsedPercent(&$xml)
    {
        return $xml["phpsysinfo"]["#"]["Memory"][0]["#"]["Percent"][0]["#"];
    }

    function _getCachedPercent(&$xml)
    {
        return $xml["phpsysinfo"]["#"]["Memory"][0]["#"]["CachedPercent"][0]["#"];
    }

    function _FileSystem($xml)
    {
        $mounts = $this->_getMounts($xml);

        for($i = 0; $i < sizeof($mounts); $i++) {

            $mount = $mounts[$i];

            $mounttype  = $mount["#"]["Type"][0]["#"];
            $mountpart = $mount["#"]["Device"][0]["#"]["Name"][0]["#"];

            //we get these in kilobytes so we convert to byte before passing to this function
            $mountfree = $this->_ConvertByte(floatval($mount["#"]["Free"][0]["#"])*1024,"0.00 KB");
            $mountused = $this->_ConvertByte(floatval($mount["#"]["Used"][0]["#"])*1024,"0.00 KB");
            $mountsize = $this->_ConvertByte(floatval($mount["#"]["Size"][0]["#"])*1024,"0.00 KB");

            $this->tpl->setKey(array(
                'SYSINFO_MOUNTPOINT'        => $this->_getMountPoint($mount),
                'SYSINFO_MOUNTTYPE'         => $mounttype,
                'SYSINFO_MOUNTPARTITION'    => $mountpart,
                'SYSINFO_MOUNTPERCENT'      => $this->bar($this->_getMountPercent($mount),100),
                'SYSINFO_MOUNTFREE'         => $mountfree,
                'SYSINFO_MOUNTUSED'         => $mountused,
                'SYSINFO_MOUNTSIZE'         => $mountsize
            ));

            $this->tpl->subst('trash2', '.mounts');
        }
    }

    function _getMounts(&$xml)
    {
        if (!isset($xml["phpsysinfo"]["#"]["FileSystem"][0]["#"]["Mount"])) {
            return array();
        }

        return $xml["phpsysinfo"]["#"]["FileSystem"][0]["#"]["Mount"];
    }

    function _getMountPoint($mount)
    {
        return $mount["#"]["MountPoint"][0]["#"];
    }

    function _getMountPercent($mount)
    {
        return $mount["#"]["Percent"][0]["#"];
    }

    function _NetworkUsage($xml)
    {
        $netdevices = $xml["phpsysinfo"]["#"]["Network"][0]["#"]["NetDevice"];

        for($i = 0; $i < sizeof($netdevices); $i++) {

            $netdevice = $netdevices[$i];

            $name   = $netdevice["#"]["Name"][0]["#"];
            $rxbytes    = $this->_ConvertByte($netdevice["#"]["RxBytes"][0]["#"],"0.00 KB");
            $txbytes    = $this->_ConvertByte($netdevice["#"]["TxBytes"][0]["#"],"0.00 KB");
            $errors     = $netdevice["#"]["Errors"][0]["#"];
            $drops  = $netdevice["#"]["Drops"][0]["#"];

            $this->tpl->setKey(array(
                'SYSINFO_DEVICENAME' => $name,
                'SYSINFO_DEVICERECEIVED'   => $rxbytes,
                'SYSINFO_DEVICESENT' => $txbytes,
                'SYSINFO_DEVICEERR'   => $errors,
                'SYSINFO_DEVICEDROP'   => $drops,
            ));

            $this->tpl->subst('trash', '.netdevices');
        }


    }

    function _SetHardware($xml)
    {
        //Getting Server Information
        $processors = $xml["phpsysinfo"]["#"]["Hardware"][0]["#"]["CPU"][0]["#"]["Number"][0]["#"];
        $cpumodel = $xml["phpsysinfo"]["#"]["Hardware"][0]["#"]["CPU"][0]["#"]["Model"][0]["#"];
        $cpuspeed = round(floatval($xml["phpsysinfo"]["#"]["Hardware"][0]["#"]["CPU"][0]["#"]["Cpuspeed"][0]["#"])/1000,2);
        if (isset($xml["phpsysinfo"]["#"]["Hardware"][0]["#"]["CPU"][0]["#"]["Cache"][0]["#"])) {
            $cpucache = $xml["phpsysinfo"]["#"]["Hardware"][0]["#"]["CPU"][0]["#"]["Cache"][0]["#"];
        } else {
            $cpucache = 'unavailable';
        }


        if($cpuspeed > 0.00) $cpuspeed = $cpuspeed." GHz";


        //Set Vitals
        $this->tpl->setKey(array(
            'SYSINFO_PROCESSORS' => $processors,
            'SYSINFO_CPUMODEL' => $cpumodel,
            'SYSINFO_CPUSPEED' => $cpuspeed,
            'SYSINFO_CPUCACHESIZE' => $cpucache,
        ));

    }

    function _SetVitals($xml)
    {
        //Getting Vitals
        $hostname = $xml["phpsysinfo"]["#"]["Vitals"][0]["#"]["Hostname"][0]["#"];
        $ipaddress = $xml["phpsysinfo"]["#"]["Vitals"][0]["#"]["IPAddr"][0]["#"];
        $per_cpuload = $xml["phpsysinfo"]["#"]["Vitals"][0]["#"]["LoadAvg"][0]["#"];
        $distroname = $xml["phpsysinfo"]["#"]["Vitals"][0]["#"]["Distro"][0]["#"];
        $kernalver = $xml["phpsysinfo"]["#"]["Vitals"][0]["#"]["Kernel"][0]["#"];
        $currentusers = $xml["phpsysinfo"]["#"]["Vitals"][0]["#"]["Users"][0]["#"];

        if ($per_cpuload > 0.00){
            $per_cpuload = $this->bar($per_cpuload,50);
        }else{
            $per_cpuload = "";
        }

        //Set Vitals
        $this->tpl->setKey(array(
            'SYSINFO_HOSTNAME'      => $hostname,
            'SYSINFO_LISTENINGIP'   => $ipaddress,
            'SYSINFO_UPTIME'        => $this->_getUptime($xml),
            'SYSINFO_LOADAVERAGE'   => $this->_getLoadAverages($xml),
            'SYSINFO_CPULOAD'       => $per_cpuload,
            'SYSINFO_DISTRONAME'    => $distroname,
            'SYSINFO_KERNALVER'     => $kernalver,
            'SYSINFO_CURRENTUSERS'  => $currentusers,
        ));

    }

    function _getLoadAverages(&$xml)
    {
        return $xml["phpsysinfo"]["#"]["Vitals"][0]["#"]["LoadAvg"][0]["#"];
    }

    function _getUptime(&$xml)
    {
        return $this->_parseUptime($xml["phpsysinfo"]["#"]["Vitals"][0]["#"]["Uptime"][0]["#"]);
    }

    //Make Human Readable
    function _ConvertByte($bytes,$emptyStr)
    {

        /*
        1 KiloByte == 1024 bytes
        1 MegaByte == 1024 KiloByte
        1 GigaByte == 1024 MegaByte
        */

         $amount = $bytes / 1024;
         $symbol = "KB";

         if ($amount > 1024){
            $symbol = "MB";
            $amount = $amount / 1024;
         }

         if ($amount > 1024){
            $symbol = "GB";
            $amount = $amount / 1024;
         }

        $returnStr = ($amount == 0) ? $emptyStr : sprintf("%01.2f", round($amount,2))." ".$symbol;
        return $returnStr;
    }

    function _parseUptime($tuptime)
    {
         $uptimeString = "";
         $secs = floor($tuptime) % 60;
         $mins = floor($tuptime / 60) % 60;
         $hours = floor($tuptime / 3600) % 24;
         $days = floor($tuptime / 86400);

         if ($days > 0) {
           $uptimeString .= $days;
           $uptimeString .= ($days == 1) ? " day " : " days ";
         }

         if ($hours > 0) {
           $uptimeString .= $hours;
           $uptimeString .= ($hours == 1) ? " hour " : " hours ";
         }

         if ($mins > 0) {
           $uptimeString .= $mins;
           $uptimeString .= ($mins == 1) ? " minute " : " minutes ";
         }

         $uptimeString .= $secs;
         $uptimeString .= ($secs == 1) ? " second " : " seconds ";

         return $uptimeString;
    }

    function bar($value, $width) {
        
        $relative = '';
        if (!NE_Lib::isPublicDir()) {
            $relative = '../';
        }
        $prefix = "blue";
        if ($value > 100) $value = 100;
        if ($value < 0) $value = 0;
        $left = 100 - $value;
        if ($left <= 10) $prefix = "red";
        $strHTML = "<!-- progress bar -->";
        $strHTML .= "<table width=\"$width%\">";
        $strHTML .= "<tr><td width=\"100%\">";
        $strHTML .= "<table width=\"100%\" height=\"14\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\" background={$relative}plugins/snapins/phpsysinfo/images/$prefix-back.gif>";
        $strHTML .= "<tr>";
        $strHTML .= "<td width=\"3\" align=\"left\"><img src={$relative}plugins/snapins/phpsysinfo/images/$prefix-start.gif></td>";
        if ($value != "0") $strHTML .= "<td width=\"$value%\" background={$relative}plugins/snapins/phpsysinfo/images/$prefix-active.gif><img src={$relative}plugins/snapins/phpsysinfo/images/zero.gif width=\"1\" height=\"1\"></td>";
        if ($value != "100" && $value != "0") $strHTML .= "<td width=\"4\"><img src={$relative}plugins/snapins/phpsysinfo/images/$prefix-divider.gif></td>";
        if ($value != "100") $strHTML .= "<td width=\"$left%\"><img src={$relative}plugins/snapins/phpsysinfo/images/zero.gif width=\"1\" height=\"1\"></td>";
        if ($value != "100" && $value != "0") $strHTML .= "<td width=\"3\" align=\"right\"><img src={$relative}plugins/snapins/phpsysinfo/images/$prefix-end.gif></td>";
        if ($value == "0" || $value == "100") $strHTML .= "<td width=\"2\" align=\"right\"><img src={$relative}plugins/snapins/phpsysinfo/images/$prefix-zeroend.gif></td>";
        $strHTML .= "</tr>";
        $strHTML .= "</table>";
        $strHTML .= "</td><td width=\"1\" class=\"text\">$value%</td></tr>";
        $strHTML .= "</table>";
        $strHTML .= "<!-- //progress bar -->";

        return $strHTML;
    }
}

?>
