Location: PHPKode > projects > EUrl the Easy URL Generator > EUrl/src/EUrl.class.php
<?php if(defined(__FILE__)){return(NULL);}define(__FILE__,TRUE);

/**
 * @brief The home of EUrl
 *
 * <PRE>
 *
 * EUrl - The Easy URL Generator
 * Copyright (C) 2005 Jason Schmidt
 *
 * To contact Jason Schmidt, you may send mail to one of the following
 * addresses.  Please note these may change in the future, but every
 * effort will be made to actively forward messages to the new
 * address(es):
 *
 * hide@address.com
 *
 * Jason Schmidt
 * 6245 Newberry Road 102
 * Indianapolis, Indiana 46256-3103
 * United States of America
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA
 *
 * </PRE>
 *
 * @author Jason Schmidt
 *
 * @file EUrl.class.php
 *
 * @version       $Revision: 1.10 $
 *
 * @date          $Date: 2005/06/01 15:58:33 $
 */

/**
 * @brief This constant is used as a name key in arrays and
 * represents the choice of protocol for the URL to be generated.
 *
 * @author Jason Schmidt
 */
define ( "EURL_VAR_PROTOCOL"       , "EURL_VAR_PROTOCOL"       );

/**
 * @brief This constant is used as a name key in arrays and
 * represents the choice of user name for the URL to be generated.
 *
 * @author Jason Schmidt
 */
define ( "EURL_VAR_USER"           , "EURL_VAR_USER"           );

/**
 * @brief This constant is used as a name key in arrays and
 * represents the choice of user password for the URL to be generated.
 *
 * @author Jason Schmidt
 */
define ( "EURL_VAR_PASS"           , "EURL_VAR_PASS"           );

/**
 * @brief This constant is used as a name key in arrays and
 * represents the choice of domain name for the URL to be generated.
 * This is ONLY for the domain, not the subdomain (such as www.)
 *
 * @author Jason Schmidt
 */
define ( "EURL_VAR_DOMAIN"         , "EURL_VAR_DOMAIN"         );

/**
 * @brief This constant is used as a name key in arrays and
 * represents the choice of sub-domain name for the URL to be
 * generated. This is ONLY for the sub-domain, such as www.
 *
 * @author Jason Schmidt
 */
define ( "EURL_VAR_SUB_DOMAIN"     , "EURL_VAR_SUB_DOMAIN"     );

/**
 * @brief This constant is used as a name key in arrays and
 * represents the choice of port number for the URL to be generated.
 *
 * @author Jason Schmidt
 */
define ( "EURL_VAR_PORT"           , "EURL_VAR_PORT"           );

/**
 * @brief This constant is used as a name key in arrays and
 * represents the choice of index path for the URL to be generated.
 * Example: /foo/bar/index.php
 *
 * @author Jason Schmidt
 */
define ( "EURL_VAR_INDEX_PATH"     , "EURL_VAR_INDEX_PATH"     );

/**
 * @brief This constant is used as a name key in arrays and
 * represents the choice of including keys in path data for the URL to
 * be generated.  This should ONLY be BOOLEAN
 *
 * @author Jason Schmidt
 */
define ( "EURL_VAR_PATH_WITH_KEYS" , "EURL_VAR_PATH_WITH_KEYS" );

/**
 * @brief This constant is used as a name key in arrays and
 * represents the choice of path data for the URL to be generated.
 * This should be an array of scalars.
 *
 * @author Jason Schmidt
 */
define ( "EURL_VAR_PATH_VARS"      , "EURL_VAR_PATH_VARS"      );

/**
 * @brief This constant is used as a name key in arrays and
 * represents the choice of effective file name for the URL to be
 * generated.  This should be an string.
 *
 * @author Jason Schmidt
 */
define ( "EURL_VAR_FILE_NAME"      , "EURL_VAR_FILE_NAME"      );

/**
 * @brief This constant is used as a name key in arrays and
 * represents the choice of GET data for the URL to be generated.
 * This should be an array of scalars.
 *
 * @author Jason Schmidt
 */
define ( "EURL_VAR_GET_VARS"       , "EURL_VAR_GET_VARS"       );

/**
 * @brief This constant is used as a name key in arrays and represents
 * the choice of fragment string for the URL to be generated.
 *
 * @author Jason Schmidt
 */
define ( "EURL_VAR_FRAGMENT"       , "EURL_VAR_FRAGMENT"       );

/**
 * @brief This constant is used as a name key in arrays and represents
 * any data that is set by default.
 *
 * @author Jason Schmidt
 */
define ( "EURL_SCOPE_INTERNAL"     , "EURL_SCOPE_INTERNAL"     );

/**
 * @brief This constant is used as a name key in arrays and represents
 * any data that is gathered from PHP global variables
 *
 * @author Jason Schmidt
 */
define ( "EURL_SCOPE_MINING"       , "EURL_SCOPE_MINING"       );

/**
 * @brief This constant is used as a name key in arrays and represents
 * any data that is gathered from the environment provided to PHP
 *
 * @author Jason Schmidt
 */
define ( "EURL_SCOPE_ENVIRONMENT"  , "EURL_SCOPE_ENVIRONMENT"  );

/**
 * @brief This constant is used as a name key in arrays and represents
 * any data that is gathered from constants the developer has set
 *
 * @author Jason Schmidt
 */
define ( "EURL_SCOPE_CONSTANTS"    , "EURL_SCOPE_CONSTANTS"    );

/**
 * @brief This constant is used as a name key in arrays and represents
 * any data that is gathered from defaults set via static calls to the
 * class
 *
 * @author Jason Schmidt
 */
define ( "EURL_SCOPE_DEFAULTS"     , "EURL_SCOPE_DEFAULTS"     );

/**
 * @brief This constant is used as a name key in arrays and represents
 * any data that is gathered from global variables using
 * $GLOBALS[EURL_VAR_*]
 *
 * @author Jason Schmidt
 */
define ( "EURL_SCOPE_GLOBAL"       , "EURL_SCOPE_GLOBAL"       );

/**
 * @brief This constant is used as a name key in arrays and represents
 * any data that is gathered from calls to an instantiated object such
 * as $eurl->SetValue(EURL_VAR_*, ...)
 *
 * @author Jason Schmidt
 */
define ( "EURL_SCOPE_SETTINGS"     , "EURL_SCOPE_SETTINGS"     );

/**
 * @brief This constant is used as a name key in arrays and represents
 * any data that is gathered from parameters passed to the Generate()
 * function such as $eurl::SetValue(array(EURL_VAR_*=>value...))
 *
 * @author Jason Schmidt
 */
define ( "EURL_SCOPE_PARAMETERS"   , "EURL_SCOPE_PARAMETERS"   );

/*NODEBUG{*/
    /** @brief Master toggle for all debug values in EUrl */
    define ( "EURL_DEBUG"                  , FALSE               );

    /** @brief Toggle debug output for EUrl::_KeyNames() method */
    define ( "EURL_DEBUG_KEYNAMES"         , EURL_DEBUG || FALSE );

    /** @brief Toggle debug output for EUrl::_ScopeOrder() method */
    define ( "EURL_DEBUG_SCOPEORDER"       , EURL_DEBUG || FALSE );

    /** @brief Toggle debug output for EUrl::_ConstantToKey() method */
    define ( "EURL_DEBUG_CONSTANTTOKEY"    , EURL_DEBUG || FALSE );

    /** @brief Toggle debug output for EUrl::_EnvironmnetToKey() method */
    define ( "EURL_DEBUG_ENVIRONMENTTOKEY" , EURL_DEBUG || FALSE );

    /** @brief Toggle debug output for EUrl::EUrl() constructor */
    define ( "EURL_DEBUG_EURL"             , EURL_DEBUG || FALSE );

    /** @brief Toggle debug output for EUrl::_Internal() method */
    define ( "EURL_DEBUG_INTERNAL"         , EURL_DEBUG || FALSE );

    /** @brief Toggle debug output for EUrl::_Mining() method */
    define ( "EURL_DEBUG_MINING"           , EURL_DEBUG || FALSE );

    /** @brief Toggle debug output for EUrl::_Environment() method */
    define ( "EURL_DEBUG_ENVIRONMENT"      , EURL_DEBUG || FALSE );

    /** @brief Toggle debug output for EUrl::_Constants() method */
    define ( "EURL_DEBUG_CONSTANTS"        , EURL_DEBUG || FALSE );

    /** @brief Toggle debug output for EUrl::_Defaults() method */
    define ( "EURL_DEBUG_DEFAULTS"         , EURL_DEBUG || FALSE );

    /** @brief Toggle debug output for EUrl::_Global() method */
    define ( "EURL_DEBUG_GLOBAL"           , EURL_DEBUG || FALSE );

    /** @brief Toggle debug output for EUrl::GetValues() method */
    define ( "EURL_DEBUG_GETVALUES"        , EURL_DEBUG || FALSE );

    /** @brief Toggle debug output for EUrl::SetValue() method */
    define ( "EURL_DEBUG_SETVALUE"         , EURL_DEBUG || FALSE );

    /** @brief Toggle debug output for EUrl::Generate() method */
    define ( "EURL_DEBUG_GENERATE"         , EURL_DEBUG || FALSE );
/*}NODEBUG*/

/**
 * @brief This magical class will take information in and turn it into
 * a nicely built URL.  In the future it may even go so far as to take
 * URLs apart for you, too.
 *
 * @todo Check input (at all stages) for invalid characters ("?=" for
 * index_path, ":" for domains users passwords and port, "/?=" for
 * path_vars, "[^a-Z0-9]" for protocol
 *
 * @ref index See the main page documentation
 *
 * @public
 *
 * @author Jason Schmidt
 */
class EUrl
{
    /**
     * @brief Store anything sent to EUrl->SetValue(EURL_VAR_*,*)
     *
     * @private
     *
     * @author Jason Schmidt
     */
    var $_Settings;

    /**
     * @brief Get a list of the constants allowed as keys
     *
     * @return Array(KeyName)
     *
     * @private
     *
     * @author Jason Schmidt
     */
    function _KeyNames()
    {
        /*NODEBUG{*/
        if(EURL_DEBUG_KEYNAMES)
        {
            print(__CLASS__."::".__FUNCTION__."(");
            foreach(func_get_args() as $arg)
            {
                print(var_export($arg,TRUE).",");
            }
            print(")\n");
        }
        /*}NODEBUG*/

        return(array(
            EURL_VAR_PROTOCOL       ,
            EURL_VAR_USER           ,
            EURL_VAR_PASS           ,
            EURL_VAR_DOMAIN         ,
            EURL_VAR_SUB_DOMAIN     ,
            EURL_VAR_PORT           ,
            EURL_VAR_INDEX_PATH     ,
            EURL_VAR_PATH_WITH_KEYS ,
            EURL_VAR_PATH_VARS      ,
            EURL_VAR_FILE_NAME      ,
            EURL_VAR_GET_VARS       ,
            EURL_VAR_FRAGMENT       ,
            ));
    }

    /**
     * @brief Get a list of scopes to take into account in order.
     * Note that FIRST value wins, so the list is in an order of
     * decreasing importance.
     *
     * @return Array(ScopeName)
     *
     * @private
     *
     * @author Jason Schmidt
     */
    function _ScopeOrder()
    {
        /*NODEBUG{*/
        if(EURL_DEBUG_SCOPEORDER)
        {
            print(__CLASS__."::".__FUNCTION__."(");
            foreach(func_get_args() as $arg)
            {
                print(var_export($arg,TRUE).",");
            }
            print(")\n");
        }
        /*}NODEBUG*/

        return(array(
            EURL_SCOPE_PARAMETERS   ,
            EURL_SCOPE_SETTINGS     ,
            EURL_SCOPE_GLOBAL       ,
            EURL_SCOPE_DEFAULTS     ,
            EURL_SCOPE_CONSTANTS    ,
            EURL_SCOPE_ENVIRONMENT  ,
            EURL_SCOPE_MINING       ,
            EURL_SCOPE_INTERNAL     ,
            ));
    }

    /**
     * @brief Get a list of constant names and their appropriate keys
     *
     * @return Array(ValName=>VarName)
     *
     * @private
     *
     * @author Jason Schmidt
     */
    function _ConstantToKey()
    {
        /*NODEBUG{*/
        if(EURL_DEBUG_CONSTANTTOKEY)
        {
            print(__CLASS__."::".__FUNCTION__."(");
            foreach(func_get_args() as $arg)
            {
                print(var_export($arg,TRUE).",");
            }
            print(")\n");
        }
        /*}NODEBUG*/

        return(array(
            "EURL_VAL_PROTOCOL"       => EURL_VAR_PROTOCOL       ,
            "EURL_VAL_USER"           => EURL_VAR_USER           ,
            "EURL_VAL_PASS"           => EURL_VAR_PASS           ,
            "EURL_VAL_DOMAIN"         => EURL_VAR_DOMAIN         ,
            "EURL_VAL_SUB_DOMAIN"     => EURL_VAR_SUB_DOMAIN     ,
            "EURL_VAL_PORT"           => EURL_VAR_PORT           ,
            "EURL_VAL_INDEX_PATH"     => EURL_VAR_INDEX_PATH     ,
            "EURL_VAL_PATH_WITH_KEYS" => EURL_VAR_PATH_WITH_KEYS ,
            "EURL_VAL_FILE_NAME"      => EURL_VAR_FILE_NAME      ,
            "EURL_VAL_FRAGMENT"       => EURL_VAR_FRAGMENT       ,
            ));
    }

    /**
     * @brief Get a list of environment variable names and their
     * appropriate keys
     *
     * @return Array(EnvName=>VarName)
     *
     * @private
     *
     * @author Jason Schmidt
     */
    function _EnvironmentToKey()
    {
        /*NODEBUG{*/
        if(EURL_DEBUG_ENVIRONMENTTOKEY)
        {
            print(__CLASS__."::".__FUNCTION__."(");
            foreach(func_get_args() as $arg)
            {
                print(var_export($arg,TRUE).",");
            }
            print(")\n");
        }
        /*}NODEBUG*/

        return(array(
            "EURL_ENV_PROTOCOL"       => EURL_VAR_PROTOCOL       ,
            "EURL_ENV_USER"           => EURL_VAR_USER           ,
            "EURL_ENV_PASS"           => EURL_VAR_PASS           ,
            "EURL_ENV_DOMAIN"         => EURL_VAR_DOMAIN         ,
            "EURL_ENV_SUB_DOMAIN"     => EURL_VAR_SUB_DOMAIN     ,
            "EURL_ENV_PORT"           => EURL_VAR_PORT           ,
            "EURL_ENV_INDEX_PATH"     => EURL_VAR_INDEX_PATH     ,
            "EURL_ENV_PATH_WITH_KEYS" => EURL_VAR_PATH_WITH_KEYS ,
            "EURL_ENV_FILE_NAME"      => EURL_VAR_FILE_NAME      ,
            "EURL_ENV_FRAGMENT"       => EURL_VAR_FRAGMENT       ,
            ));
    }

    /**
     * @brief Constructor
     *
     * @return Reference to self
     *
     * @public
     *
     * @author Jason Schmidt
     */
    function EUrl()
    {
        /*NODEBUG{*/
        if(EURL_DEBUG_EURL)
        {
            print(__CLASS__."::".__FUNCTION__."(");
            foreach(func_get_args() as $arg)
            {
                print(var_export($arg,TRUE).",");
            }
            print(")\n");
        }
        /*}NODEBUG*/

        $this->_Settings = array();
        foreach(EUrl::_KeyNames() as $key)
        {
            $this->_Settings[$key] = NULL;
        }
    }

    /**
     * @brief Get internal default values for each variable
     *
     * @note This returns by reference because there's no point in
     * copying the memory locations every call
     *
     * @return &Array(EURL_VAR_*=>Value)
     *
     * @private
     *
     * @author Jason Schmidt
     */
    function & _Internal()
    {
        /*NODEBUG{*/
        if(EURL_DEBUG_INTERNAL)
        {
            print(__CLASS__."::".__FUNCTION__."(");
            foreach(func_get_args() as $arg)
            {
                print(var_export($arg,TRUE).",");
            }
            print(")\n");
        }
        /*}NODEBUG*/

        static $defaults = array(
            EURL_VAR_PROTOCOL       => "http"      ,
            EURL_VAR_USER           => NULL        ,
            EURL_VAR_PASS           => NULL        ,
            EURL_VAR_DOMAIN         => "localhost" ,
            EURL_VAR_SUB_DOMAIN     => NULL        ,
            EURL_VAR_PORT           => NULL        ,
            EURL_VAR_INDEX_PATH     => NULL        ,
            EURL_VAR_PATH_WITH_KEYS => FALSE       ,
            EURL_VAR_PATH_VARS      => NULL        ,
            EURL_VAR_FILE_NAME      => NULL        ,
            EURL_VAR_GET_VARS       => NULL        ,
            EURL_VAR_FRAGMENT       => NULL        ,
            );

        return($defaults);
    }

    /**
     * @brief Get values extracted from PHP variables (this should
     * only need to be run once)
     *
     * @note This returns by reference because there's no point in
     * copying the memory locations every call
     *
     * @return Array(EURL_VAR_*=>Value)
     *
     * @private
     *
     * @author Jason Schmidt
     */
    function & _Mining()
    {
        /*NODEBUG{*/
        if(EURL_DEBUG_MINING)
        {
            print(__CLASS__."::".__FUNCTION__."(");
            foreach(func_get_args() as $arg)
            {
                print(var_export($arg,TRUE).",");
            }
            print(")\n");
        }
        /*}NODEBUG*/

        static $return = NULL;

        if(NULL === $return)
        {
            $return = array(
                EURL_VAR_PROTOCOL       => NULL,
                EURL_VAR_USER           => NULL,
                EURL_VAR_PASS           => NULL,
                EURL_VAR_DOMAIN         => NULL,
                EURL_VAR_SUB_DOMAIN     => NULL,
                EURL_VAR_PORT           => NULL,
                EURL_VAR_INDEX_PATH     => NULL,
                EURL_VAR_PATH_WITH_KEYS => NULL,
                EURL_VAR_PATH_VARS      => NULL,
                EURL_VAR_GET_VARS       => NULL,
                EURL_VAR_FRAGMENT       => NULL,
                );

            if(isset($_SERVER))
            {
                if(isset($_SERVER['HTTPS']))
                {
                    /*NODEBUG{*/
                    if(EURL_DEBUG_MINING)
                    {
                        print(__CLASS__."::".__FUNCTION__."(): ");
                        print("SSL Enabled\n");
                    }
                    /*}NODEBUG*/

                    $return[EURL_VAR_PROTOCOL] = "https";
                }
                if(isset($_SERVER['PHP_AUTH_USER']))
                {
                    /*NODEBUG{*/
                    if(EURL_DEBUG_MINING)
                    {
                        print(__CLASS__."::".__FUNCTION__."(): ");
                        print("User found: ");
                        print($_SERVER['PHP_AUTH_USER']);
                        print("\n");
                    }
                    /*}NODEBUG*/

                    $return[EURL_VAR_USER] = $_SERVER['PHP_AUTH_USER'];
                }
                if(isset($_SERVER['PHP_AUTH_PW']))
                {
                    /*NODEBUG{*/
                    if(EURL_DEBUG_MINING)
                    {
                        print(__CLASS__."::".__FUNCTION__."(): ");
                        print("Password found: ");
                        print($_SERVER['PHP_AUTH_PW']);
                        print("\n");
                    }
                    /*}NODEBUG*/

                    $return[EURL_VAR_PASS] = $_SERVER['PHP_AUTH_PW'];
                }
                if(isset($_SERVER['HTTP_HOST']))
                {
                    $host  = $_SERVER['HTTP_HOST'];
                    $regex = "/^(([^\.]+)\.){0,}([^\.]+\..{2,3})$/";

                    if(preg_match($regex, $host, $match))
                    {
                        $subdomain = $match[2];
                        $domain    = $match[3];

                        if($subdomain)
                        {
                            /*NODEBUG{*/
                            if(EURL_DEBUG_MINING)
                            {
                                print(__CLASS__."::".__FUNCTION__."(): ");
                                print("Subdomain found: ");
                                print($subdomain);
                                print("\n");
                            }
                            /*}NODEBUG*/

                            $return[EURL_VAR_SUB_DOMAIN] = $subdomain;
                        }

                        /*NODEBUG{*/
                        if(EURL_DEBUG_MINING)
                        {
                            print(__CLASS__."::".__FUNCTION__."(): ");
                            print("Domain found: ");
                            print($domain);
                            print("\n");
                        }
                        /*}NODEBUG*/

                        $return[EURL_VAR_DOMAIN] = $domain;
                    }
                }
                if(isset($_SERVER['SCRIPT_NAME']))
                {
                    $path = $_SERVER['SCRIPT_NAME'];
                    $path = trim($path, "\\/");

                    /*NODEBUG{*/
                    if(EURL_DEBUG_MINING)
                    {
                        print(__CLASS__."::".__FUNCTION__."(): ");
                        print("Scriptname found: ");
                        print($path);
                        print("\n");
                    }
                    /*}NODEBUG*/

                    $return[EURL_VAR_INDEX_PATH] = $path;
                }
                if(isset($_SERVER['SERVER_PORT']))
                {
                    /*NODEBUG{*/
                    if(EURL_DEBUG_MINING)
                    {
                        print(__CLASS__."::".__FUNCTION__."(): ");
                        print("Port number found: ");
                        print($_SERVER['SERVER_PORT']);
                        print("\n");
                    }
                    /*}NODEBUG*/

                    $return[EURL_VAR_PORT] = $_SERVER['SERVER_PORT'];
                }
            }
        }

        return($return);
    }

    /**
     * @brief Get values stored in the environment named EURL_VAR_*
     * (this should only need to be run once)
     *
     * @note This returns by reference because there's no point in
     * copying the memory locations every call
     *
     * @return &Array(EURL_VAR_*=>&$_ENV[Value])
     *
     * @private
     *
     * @author Jason Schmidt
     */
    function & _Environment()
    {
        /*NODEBUG{*/
        if(EURL_DEBUG_ENVIRONMENT)
        {
            print(__CLASS__."::".__FUNCTION__."(");
            foreach(func_get_args() as $arg)
            {
                print(var_export($arg,TRUE).",");
            }
            print(")\n");
        }
        /*}NODEBUG*/

        static $return = NULL;

        if(NULL === $return)
        {
            foreach(EUrl::_EnvironmentToKey() as $env_key => $key)
            {
                if(isset($_ENV[$env_key]))
                {
                    /*NODEBUG{*/
                    if(EURL_DEBUG_ENVIRONMENT)
                    {
                        print(__CLASS__."::".__FUNCTION__."(): ");
                        print("$key found in environment\n");
                    }
                    /*}NODEBUG*/

                    $return[$key] =& $_ENV[$env_key];
                }
                elseif(isset($_SERVER[$env_key]))
                {
                    /*NODEBUG{*/
                    if(EURL_DEBUG_ENVIRONMENT)
                    {
                        print(__CLASS__."::".__FUNCTION__."(): ");
                        print("$key found in server vars\n");
                    }
                    /*}NODEBUG*/

                    $return[$key] =& $_SERVER[$env_key];
                }
                else
                {
                    $return[$key] =  NULL;
                }
            }
        }

        return($return);
    }

    /**
     * @brief Get values stored in the constants EURL_VAL_* (this will
     * be run each time because you may decide to define MORE
     * constants)
     *
     * @note This returns by reference because there's no point in
     * copying the memory locations every call
     *
     * @return Array(EURL_VAR_*=>Value)
     *
     * @private
     *
     * @author Jason Schmidt
     */
    function & _Constants()
    {
        /*NODEBUG{*/
        if(EURL_DEBUG_CONSTANTS)
        {
            print(__CLASS__."::".__FUNCTION__."(");
            foreach(func_get_args() as $arg)
            {
                print(var_export($arg,TRUE).",");
            }
            print(")\n");
        }
        /*}NODEBUG*/

        static $defined = array();

        // For each allowable constant
        foreach(EUrl::_ConstantToKey() as $val_key => $key)
        {
            // If the current value is NULL
            if(!isset($defined[$key]))
            {
                // And we have a new value...
                if(defined($val_key))
                {
                    /*NODEBUG{*/
                    if(EURL_DEBUG_CONSTANTS)
                    {
                        print(__CLASS__."::".__FUNCTION__."(): ");
                        print("$key found in constant\n");
                    }
                    /*}NODEBUG*/

                    $defined[$key] = constant($val_key);
                }
                else
                {
                    $defined[$key] = NULL;
                }
            }
        }

        return($defined);
    }

    /**
     * @brief Get a reference to a static variable for storing
     * defaults
     *
     * @return Reference to array
     *
     * @private
     *
     * @author Jason Schmidt
     */
    function & _Defaults()
    {
        /*NODEBUG{*/
        if(EURL_DEBUG_DEFAULTS)
        {
            print(__CLASS__."::".__FUNCTION__."(");
            foreach(func_get_args() as $arg)
            {
                print(var_export($arg,TRUE).",");
            }
            print(")\n");
        }
        /*}NODEBUG*/

        static $internal = NULL;

        if(NULL === $internal)
        {
            /*NODEBUG{*/
            if(EURL_DEBUG_DEFAULTS)
            {
                print(__CLASS__."::".__FUNCTION__."(): ");
                print("Initializing static defaults\n");
            }
            /*}NODEBUG*/

            $internal = array();
            foreach(EUrl::_KeyNames() as $key)
            {
                $internal[$key] = NULL;
            }
        }

        return($internal);
    }

    /**
     * @brief Get values stored in the $GLOBALS[EURL_VAR_*] by
     * REFERENCE
     *
     * @return &Array(&$GLOBALS[...])
     *
     * @private
     *
     * @author Jason Schmidt
     */
    function & _Global()
    {
        /*NODEBUG{*/
        if(EURL_DEBUG_GLOBAL)
        {
            print(__CLASS__."::".__FUNCTION__."(");
            foreach(func_get_args() as $arg)
            {
                print(var_export($arg,TRUE).",");
            }
            print(")\n");
        }
        /*}NODEBUG*/

        static $global_refs = NULL;

        if(NULL === $global_refs)
        {
            /*NODEBUG{*/
            if(EURL_DEBUG_GLOBAL)
            {
                print(__CLASS__."::".__FUNCTION__."(): ");
                print("Referencing _GLOBALS\n");
            }
            /*}NODEBUG*/

            foreach(EUrl::_KeyNames() as $key)
            {
                $global_refs[$key] =& $GLOBALS[$key];
            }
        }

        return($global_refs);
    }

    /**
     * @brief Get the merged variable list
     *
     * @param $Params NULL || Array(EURL_VAR_*=>Value) Optional:
     * Values to return in the EURL_SCOPE_PARAMETERS
     *
     * @return Reference to variable namespace
     *
     * @public
     *
     * @author Jason Schmidt
     */
    function GetValues($Params=NULL)
    {
        /*NODEBUG{*/
        if(EURL_DEBUG_GETVALUES)
        {
            print(__CLASS__."::".__FUNCTION__."(");
            foreach(func_get_args() as $arg)
            {
                print(var_export($arg,TRUE).",");
            }
            print(")\n");
        }
        /*}NODEBUG*/

        static $empty       = array();
        static $static_vars = NULL;

        // The static bits which don't change, IE: Internal defaults,
        // data mined from PHP, etc.
        if(NULL === $static_vars)
        {
            /*NODEBUG{*/
            if(EURL_DEBUG_GETVALUES)
            {
                print(__CLASS__."::".__FUNCTION__."(): ");
                print("Initializing completely static returns\n");
            }
            /*}NODEBUG*/

            $static_vars = array();
            $static_vars[EURL_SCOPE_INTERNAL   ] =& EUrl::_Internal();
            $static_vars[EURL_SCOPE_CONSTANTS  ] =& EUrl::_Constants();
            $static_vars[EURL_SCOPE_MINING     ] =& EUrl::_Mining();
            $static_vars[EURL_SCOPE_ENVIRONMENT] =& EUrl::_Environment();
            $static_vars[EURL_SCOPE_DEFAULTS   ] =& EUrl::_Defaults();
            $static_vars[EURL_SCOPE_GLOBAL     ] =& EUrl::_Global();
        }

        // Now copy all our static variables and referenced variables in
        $vars = array();

        // We rerun this each time because you may have defined MORE
        // constants since the last time we did this.
        EUrl::_Constants();

        // If we're locally instantiated, we'll have settings to grab
        // as well
        if(isset($this))
        {
            /*NODEBUG{*/
            if(EURL_DEBUG_GETVALUES)
            {
                print(__CLASS__."::".__FUNCTION__."(): ");
                print("Getting instantiated settings, too\n");
            }
            /*}NODEBUG*/

            $vars[EURL_SCOPE_SETTINGS] =& $this->_Settings;
        }

        // If they've passed parameters to the Generate function, we
        // want to include them here...
        if(NULL !== $Params)
        {
            /*NODEBUG{*/
            if(EURL_DEBUG_GETVALUES)
            {
                print(__CLASS__."::".__FUNCTION__."(): ");
                print("Including parameters in parse\n");
            }
            /*}NODEBUG*/

            $vars[EURL_SCOPE_PARAMETERS] =& $Params;
        }

        // For each scope
        $return     = array();
        $scopeorder = EUrl::_ScopeOrder();
        $keynames   = EUrl::_KeyNames();
        foreach($scopeorder as $scope)
        {
            $scoped =& $empty;

            if(isset($static_vars[$scope]))
            {
                $scoped =& $static_vars[$scope];
            }

            if(isset($vars[$scope]))
            {
                $scoped =& $vars[$scope];
            }

            foreach($keynames as $key)
            {
                if(!isset($return[$key]) && isset($scoped[$key]))
                {
                    /*NODEBUG{*/
                    if(EURL_DEBUG_GETVALUES)
                    {
                        print(__CLASS__."::".__FUNCTION__."(): ");
                        print("$key from $scope\n");
                    }
                    /*}NODEBUG*/

                    $return[$key] = $scoped[$key];
                }
            }
        }

        return($return);
    }

    /**
     * @brief Set a default or setting value
     *
     * @code
     * // If you wish to set a default, call this function statically:
     * EUrl::SetValue( EURL_VAR_DOMAIN , "MyDomain.com" );
     *
     * // If you wish to set a locally instantiated value:
     * $ExternalLink = new EUrl();
     * $ExternalLink->SetValue( EURL_VAR_DOMAIN , "SomeoneElse.com" );
     * @endcode
     *
     * @warning Calls trigger_error if you pass an invalid $VarName,
     * but does NOT error on invalid $Value.  That happens when you
     * attempt to EUrl::Generate()
     *
     * @param $VarName Constant Required: EURL_VAR_*
     *
     * @param $Value Mixed Required: See EURL_VAR_* For appropriate
     * type
     *
     * @return NULL
     *
     * @public
     *
     * @author Jason Schmidt
     */
    function SetValue( $VarName, $Value )
    {
        /*NODEBUG{*/
        if(EURL_DEBUG_SETVALUE)
        {
            print(__CLASS__."::".__FUNCTION__."(");
            foreach(func_get_args() as $arg)
            {
                print(var_export($arg,TRUE).",");
            }
            print(")\n");
        }
        /*}NODEBUG*/

        // Check key name
        if(!in_array($VarName, EUrl::_KeyNames()))
        {
            /*NODEBUG{*/
            if(EURL_DEBUG_SETVALUE)
            {
                print(__CLASS__."::".__FUNCTION__."(): ");
                print("Unknown variable $VarName\n");
            }
            /*}NODEBUG*/

            trigger_error(
                "Unknown EURL_VAR_*: "
                . var_export($VarName, TRUE)
                , E_USER_ERROR
                );
        }

        // Check scope to put it in
        if(isset($this))
        {
            /*NODEBUG{*/
            if(EURL_DEBUG_SETVALUE)
            {
                print(__CLASS__."::".__FUNCTION__."(): ");
                print("Storing $VarName in instantiated object\n");
            }
            /*}NODEBUG*/

            $array =& $this->_Settings;
        }
        else
        {
            /*NODEBUG{*/
            if(EURL_DEBUG_SETVALUE)
            {
                print(__CLASS__."::".__FUNCTION__."(): ");
                print("Storing $VarName in static defaults\n");
            }
            /*}NODEBUG*/

            $array =& EUrl::_Defaults();
        }

        // Store value
        $array[$VarName] = $Value;

        // Return null
        return(NULL);
    }

    /**
     * @brief Build a URL!  The heart of gold for this class.
     *
     * @param $Extra Array(EURL_VAR_*=>Value) Optional
     *
     * @return String URL
     *
     * @public
     *
     * @author Jason Schmidt
     */
    function Generate($Extra=NULL)
    {
        /*NODEBUG{*/
        if(EURL_DEBUG_GENERATE)
        {
            print(__CLASS__."::".__FUNCTION__."(");
            foreach(func_get_args() as $arg)
            {
                print(var_export($arg,TRUE).",");
            }
            print(")\n");
        }
        /*}NODEBUG*/

        // Check input
        $KeyNames = EUrl::_KeyNames();
        if(is_array($Extra))
        {
            foreach($Extra as $Key => $Value)
            {
                // Check key name
                if(!in_array($Key, $KeyNames))
                {
                    /*NODEBUG{*/
                    if(EURL_DEBUG_GENERATE)
                    {
                        print(__CLASS__."::".__FUNCTION__."(): ");
                        print("Unknown variable $Key\n");
                    }
                    /*}NODEBUG*/

                    trigger_error(
                        "Unknown EURL_VAR_*: "
                        . var_export($Key, TRUE)
                        , E_USER_ERROR
                        );
                }
            }
        }
        elseif(NULL !== $Extra)
        {
            /*NODEBUG{*/
            if(EURL_DEBUG_GENERATE)
            {
                print(__CLASS__."::".__FUNCTION__."(): ");
                print("Unexpected parameter: ");
                print(var_export($Extra, TRUE));
                print("\n");
            }
            /*}NODEBUG*/

            // Error on invalid input
            trigger_error(
                "Extra must be NULL or Array: "
                . var_export($Extra, TRUE)
                , E_USER_ERROR
                );
        }

        // Depending on scope...
        if(isset($this))
        {
            /*NODEBUG{*/
            if(EURL_DEBUG_GENERATE)
            {
                print(__CLASS__."::".__FUNCTION__."(): ");
                print("Calling from instantiated object\n");
            }
            /*}NODEBUG*/

            $vars = $this->GetValues($Extra);
        }
        else
        {
            /*NODEBUG{*/
            if(EURL_DEBUG_GENERATE)
            {
                print(__CLASS__."::".__FUNCTION__."(): ");
                print("Calling statically\n");
            }
            /*}NODEBUG*/

            $vars = EUrl::GetValues($Extra);
        }

        // Start with an empty string
        $url = "";

        // Add protocol
        if(!isset($vars[EURL_VAR_PROTOCOL]))
        {
            /*NODEBUG{*/
            if(EURL_DEBUG_GENERATE)
            {
                print(__CLASS__."::".__FUNCTION__."(): ");
                print("Protocol must be defined\n");
            }
            /*}NODEBUG*/

            trigger_error(
                "No protocol set!"
                , E_USER_ERROR
                );
        }
        $url .= $vars[EURL_VAR_PROTOCOL];
        $url .= "://";

        // Add username and password
        if(isset($vars[EURL_VAR_USER]))
        {
            /*NODEBUG{*/
            if(EURL_DEBUG_GENERATE)
            {
                print(__CLASS__."::".__FUNCTION__."(): ");
                print("Including user in URL\n");
            }
            /*}NODEBUG*/

            $url .= rawurlencode($vars[EURL_VAR_USER]);
            if(isset($vars[EURL_VAR_PASS]))
            {
                /*NODEBUG{*/
                if(EURL_DEBUG_GENERATE)
                {
                    print(__CLASS__."::".__FUNCTION__."(): ");
                    print("Including password in URL\n");
                }
                /*}NODEBUG*/

                $url .= ':'.rawurlencode($vars[EURL_VAR_PASS]);
            }
            $url .= '@';
        }

        // Add domain name
        if(isset($vars[EURL_VAR_SUB_DOMAIN]))
        {
            /*NODEBUG{*/
            if(EURL_DEBUG_GENERATE)
            {
                print(__CLASS__."::".__FUNCTION__."(): ");
                print("Including sub-domain\n");
            }
            /*}NODEBUG*/

            $url .= $vars[EURL_VAR_SUB_DOMAIN];
            $url .= ".";
        }
        if(!isset($vars[EURL_VAR_DOMAIN]))
        {
            /*NODEBUG{*/
            if(EURL_DEBUG_GENERATE)
            {
                print(__CLASS__."::".__FUNCTION__."(): ");
                print("Domain must be set\n");
            }
            /*}NODEBUG*/

            trigger_error(
                "No domain set!"
                , E_USER_ERROR
                );
        }
        $url .= $vars[EURL_VAR_DOMAIN];

        // Add port
        if(isset($vars[EURL_VAR_PORT]) && $vars[EURL_VAR_PORT])
        {
            /*NODEBUG{*/
            if(EURL_DEBUG_GENERATE)
            {
                print(__CLASS__."::".__FUNCTION__."(): ");
                print("Adding port number to URL\n");
            }
            /*}NODEBUG*/

            $url .= ":";
            $url .= $vars[EURL_VAR_PORT];
        }
        $url .= "/";

        // Add index file
        if(isset($vars[EURL_VAR_INDEX_PATH]))
        {
            /*NODEBUG{*/
            if(EURL_DEBUG_GENERATE)
            {
                print(__CLASS__."::".__FUNCTION__."(): ");
                print("Adding index file path to URL\n");
            }
            /*}NODEBUG*/

            $url .= $vars[EURL_VAR_INDEX_PATH];
        }

        // Add path variables data
        if(!isset($vars[EURL_VAR_PATH_WITH_KEYS]))
        {
            /*NODEBUG{*/
            if(EURL_DEBUG_GENERATE)
            {
                print(__CLASS__."::".__FUNCTION__."(): ");
                print("No determination for handling PATH vars found\n");
            }
            /*}NODEBUG*/

            trigger_error(
                "EURL_VAR_PATH_WITH_KEYS must be boolean!"
                , E_USER_ERROR
                );
        }
        if(isset($vars[EURL_VAR_PATH_VARS]))
        {
            /*NODEBUG{*/
            if(EURL_DEBUG_GENERATE)
            {
                print(__CLASS__."::".__FUNCTION__."(): ");
                print("Including PATH variables in URL\n");
            }
            /*}NODEBUG*/

            foreach($vars[EURL_VAR_PATH_VARS] as $key=>$value)
            {
                if($vars[EURL_VAR_PATH_WITH_KEYS])
                {
                    $url .= "/";
                    $url .= rawurlencode($key  );
                }

                $url .= "/";
                $url .= rawurlencode($value);
            }
        }

        // Add effective file name
        if(isset($vars[EURL_VAR_FILE_NAME]))
        {
            /*NODEBUG{*/
            if(EURL_DEBUG_GENERATE)
            {
                print(__CLASS__."::".__FUNCTION__."(): ");
                print("Including an effective file in URL\n");
            }
            /*}NODEBUG*/

            $url .= "/";
            $url .= $vars[EURL_VAR_FILE_NAME];
        }

        // Add GET parameters
        if(isset($vars[EURL_VAR_GET_VARS]) && $vars[EURL_VAR_GET_VARS])
        {
            /*NODEBUG{*/
            if(EURL_DEBUG_GENERATE)
            {
                print(__CLASS__."::".__FUNCTION__."(): ");
                print("Including GET variables in URL\n");
            }
            /*}NODEBUG*/

            $gets = array();
            foreach($vars[EURL_VAR_GET_VARS] as $key=>$value)
            {
                $gets[] =     rawurlencode($key  ).
                          '='.rawurlencode($value);
            }
            $url .= "?";
            $url .= join("&",$gets);
        }

        // Add Fragment
        if(isset($vars[EURL_VAR_FRAGMENT]) && $vars[EURL_VAR_FRAGMENT])
        {
            /*NODEBUG{*/
            if(EURL_DEBUG_GENERATE)
            {
                print(__CLASS__."::".__FUNCTION__."(): ");
                print("Including FRAGMENT in URL\n");
            }
            /*}NODEBUG*/

            $url .= "#";
            $url .= $vars[EURL_VAR_FRAGMENT];
        }

        /*NODEBUG{*/
        if(EURL_DEBUG_GENERATE)
        {
            print(__CLASS__."::".__FUNCTION__."(): ");
            print("$url\n");
        }
        /*}NODEBUG*/

        return($url);
    }
}

?>
Return current item: EUrl the Easy URL Generator