<?php
/**
 * The Server:: class provides functions to determine server
 * configuration settings.
 *
 * $Horde: horde/lib/Server.php,v 1.26 2003/08/21 15:56:03 mdjukic Exp $
 *
 * Copyright 2002-2003 Michael Slusarz <slusarz@bigworm.colorado.edu>
 *
 * See the enclosed file COPYING for license information (LGPL). If you
 * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
 *
 * @author  Michael Slusarz <slusarz@bigworm.colorado.edu>
 * @version $Revision: 1.26 $
 * @since   Horde 3.0
 * @package horde.server
 */
class Server {

    /**
     * Determine if we are using a Secure (SSL) connection.
     *
     * @access public
     *
     * @return boolean  True if using SSL, false if not.
     */
    function usingSSLConnection()
    {
        return ((array_key_exists('HTTPS', $_SERVER) &&
                 ($_SERVER['HTTPS'] == 'on')) ||
                getenv('SSL_PROTOCOL_VERSION'));
    }

    /**
     * Determine if output compression can be used.
     *
     * @access public
     *
     * @return boolean  True if output compression can be used, false if not.
     */
    function allowOutputCompression()
    {
        require_once HORDE_BASE . '/lib/Browser.php';
        $browser = &Browser::singleton();

        /* Turn off compression for buggy browsers. */
        if ($browser->hasQuirk('buggy_compression')) {
            return false;
        }

        return (ini_get('zlib.output_compression') == '' &&
                ini_get('output_handler') != 'ob_gzhandler');
    }

    /**
     * Determine if files can be uploaded to the system.
     *
     * @access public
     *
     * @return integer  If uploads allowed, returns the maximum size of the
     *                  upload in bytes.  Returns 0 if uploads are not
     *                  allowed.
     */
    function allowFileUploads()
    {
        if (ini_get('file_uploads')) {
            if (($dir = ini_get('upload_tmp_dir')) &&
                !is_writable($dir)) {
                return 0;
            }
            $size = ini_get('upload_max_filesize');
            switch (strtolower(substr($size, -1, 1))) {
            case 'k':
                $size = intval(floatval($size) * 1024);
                break;
            case 'm':
                $size = intval(floatval($size) * 1024 * 1024);
                break;
            default:
                $size = intval($size);
                break;
            }
            return $size;
        } else {
            return 0;
        }
    }

    /**
     * Determines if the file was uploaded or not.  If not, will return the
     * appropriate error message.
     *
     * @access public
     *
     * @param string $field           The name of the field containing the
     *                                uploaded file.
     * @param optional string $name   The file description string to use in the
     *                                error message.  Default: 'file'.
     *
     * @return mixed  True on success, PEAR_Error on error.
     */
    function wasFileUploaded($field, $name = null)
    {
        if (is_null($name)) {
            $name = _("file");
        }

        /* TODO: These error constants appeared in PHP 4.3.0. This code
           should be removed once Horde requires PHP 4.3.0+. */
        if (!defined('UPLOAD_ERR_OK')) {
            $upload_const = array(
                'UPLOAD_ERR_OK' => 0,
                'UPLOAD_ERR_INI_SIZE' => 1,
                'UPLOAD_ERR_FORM_SIZE' => 2,
                'UPLOAD_ERR_PARTIAL' => 3,
                'UPLOAD_ERR_NO_FILE' => 4
            );
            foreach ($upload_const as $key => $val) {
                define($key, $val);
            }
        }

        if (!($uploadSize = Server::allowFileUploads())) {
            return PEAR::raiseError(_("File uploads not supported."));
        }

        /* Get any index on the field name. */
        require_once HORDE_BASE . '/lib/Array.php';
        $index = Horde_Array::getArrayParts($field, $base, $keys);

        if ($index) {
            /* Index present, fetch the error var to check. */
            $keys_path = array_merge(array($base, 'error'), $keys);
            $error = Horde_Array::getElement($_FILES, $keys_path);
            /* Index present, fetch the tmp_name var to check. */
            $keys_path = array_merge(array($base, 'tmp_name'), $keys);
            $tmp_name = Horde_Array::getElement($_FILES, $keys_path);
        } else {
            /* No index, simple set up of vars to check. */
            $error = $_FILES[$field]['error'];
            $tmp_name = $_FILES[$field]['tmp_name'];
        }

        if (!isset($_FILES) || ($error == UPLOAD_ERR_NO_FILE)) {
            return PEAR::raiseError(sprintf(_("There was a problem with the file upload: No %s was uploaded."), $name));
        } elseif (($error == UPLOAD_ERR_OK) && is_uploaded_file($tmp_name)) {
            return true;
        } elseif (($error == UPLOAD_ERR_INI_SIZE) ||
                  ($error == UPLOAD_ERR_FORM_SIZE)) {
            return PEAR::raiseError(sprintf(_("There was a problem with the file upload: The %s was larger than the maximum allowed size (%d bytes)."), $name, $uploadSize));
        } elseif ($error == UPLOAD_ERR_PARTIAL) {
            return PEAR::raiseError(sprintf(_("There was a problem with the file upload: The %s was only partially uploaded."), $name));
        }
    }

    function getUploadedFileType($field)
    {
        /* Get any index on the field name. */
        require_once HORDE_BASE . '/lib/Array.php';
        $index = Horde_Array::getArrayParts($field, $base, $keys);

        if ($index) {
            /* Index present, fetch the mime type var to check. */
            $keys_path = array_merge(array($base, 'type'), $keys);
            $type = Horde_Array::getElement($_FILES, $keys_path);
            $keys_path= array_merge(array($base, 'tmp_name'), $keys);
            $tmp_name = Horde_Array::getElement($_FILES, $keys_path);
        } else {
            /* No index, simple set up of vars to check. */
            $type = $_FILES[$field]['type'];
            $tmp_name = $_FILES[$field]['tmp_name'];
        }

        if (empty($type) || ($type == 'application/octet-stream')) {
            /* Type wasn't set on upload, try analising the upload. */
            require_once HORDE_BASE . '/lib/MIME/Magic.php';
            if (!($type = MIME_Magic::analyzeFile($tmp_name))) {
                if ($index) {
                    /* Get the name value. */
                    $keys_path = array_merge(array($base, 'name'), $keys);
                    $name = Horde_Array::getElement($_FILES, $keys_path);
                    /* Work out the type from the file name. */
                    $type = MIME_Magic::filenameToMIME($name);
                    /* Set the type. */
                    $keys_path = array_merge(array($base, 'type'), $keys);
                    Horde_Array::getElement($_FILES, $keys_path, $type);
                } else {
                    /* Work out the type from the file name. */
                    $type = MIME_Magic::filenameToMIME($_FILES[$field]['name']);
                    /* Set the type. */
                    $_FILES[$field]['type'] = MIME_Magic::filenameToMIME($_FILES[$field]['name']);
                }
            }
        }

        return $type;
    }

    /**
     * Returns the Web server being used.
     * PHP string list built from the PHP 'configure' script.
     *
     * @access public
     *
     * @return string  A web server identification string.
     * <pre>
     * 'aolserver' = AOL Server
     * 'apache1'   = Apache 1.x
     * 'apache2'   = Apache 2.x
     * 'caudium'   = Caudium
     * 'cgi'       = Unknown server - PHP built as CGI program
     * 'isapi'     = Zeus ISAPI
     * 'nsapi'     = NSAPI
     * 'phttpd'    = PHTTPD
     * 'pi3web'    = Pi3Web
     * 'roxen'     = Roxen/Pike
     * 'servlet'   = Servlet
     * 'thttpd'    = thttpd
     * 'tux'       = Tux
     * 'webjames'  = Webjames
     * </pre>
     */
    function webServerID()
    {
        $server = php_sapi_name();

        if ($server == 'apache') {
            return 'apache1';
        } elseif (($server == 'apache2filter') ||
                  ($server == 'apache2handler')) {
            return 'apache2';
        } else {
            return $server;
        }
    }

    /**
     * Returns the server protocol in use on the current server.
     *
     * @access public
     *
     * @return string  The HTTP server protocol version.
     */
    function HTTPProtocol()
    {
        if (array_key_exists('SERVER_PROTOCOL', $_SERVER)) {
            if (($pos = strrpos($_SERVER['SERVER_PROTOCOL'], '/'))) {
                return substr($_SERVER['SERVER_PROTOCOL'], $pos + 1);
            }
        }

        return null;
    }
}
