CHANGES TO REMOVE register_globals REQUIREMENT for .../catalog - V 1.4 - Richard Bentley 06/03/2006
---------------------------------------------------------------------------------------------------

Before proceding, read the README file !

In the following instructions, I have commented out rather than delete the existing code (where
applicable). Of course, you are free to do what you like.

The following files need to be modified :

.../catalog/install/includes/application.php
.../catalog/includes/application_top.php
.../catalog/include/classes/order.php
.../catalog/includes/functions/general.php
.../catalog/includes/functions/gzip_compression.php
.../catalog/includes/functions/sessions.php
.../catalog/includes/languages/english/password_forgotten.php
.../catalog/includes/languages/espanol/password_forgotten.php
.../catalog/includes/languages/german/password_forgotten.php

================================================================================

.../catalog/install/includes/application.php
--------------------------------------------

NOTE: If you have already installed OSC (ie - run through the installation procedure),
----  then this file may not exist; once installation of OSC is complete, you should
      delete the whole of the .../catalog/install/ directory - it is not needed after
      installation and having it hanging around is a security risk

Comment out / delete the check at the top of the file...

// check if register_globals is enabled.
// since this is a temporary measure this message is hardcoded. The requirement will be removed before 2.2 is finalized.
ed.
// >>> BEGIN REGISTER_GLOBALS
//  if (function_exists('ini_get')) {
//    ini_get('register_globals') or exit('FATAL ERROR: register_globals is disabled in php.ini, please enable it!');
//  }
// <<< END REGISTER_GLOBALS

================================================================================

.../catalog/includes/application_top.php
----------------------------------------

Comment out / delete the check at the top of the file...

// check if register_globals is enabled.
// since this is a temporary measure this message is hardcoded. The requirement will be removed before 2.2 is finalized.
// >>> BEGIN REGISTER_GLOBALS
//  if (function_exists('ini_get')) {
//    ini_get('register_globals') or exit('Server Requirement Error: register_globals is disabled in your PHP configuration. This can be enabled in your php.ini configuration file or in the .htaccess file in your catalog directory.');
//  }
// <<< END REGISTER_GLOBALS

================================================================================

.../catalog/includes/classes/order.php
--------------------------------------

Change the EXISTING function...

    order()

...to read as follows :

   function order($order_id = '') {
      $this->info = array();
      $this->totals = array();
      $this->products = array();
      $this->customer = array();
      $this->delivery = array();

      if (tep_not_null($order_id)) {
        $this->query($order_id);
      } else {
// >>> BEGIN REGISTER_GLOBALS
        link_post_variable('cc_type'); 
        link_post_variable('cc_owner'); 
        link_post_variable('cc_number'); 
        link_post_variable('cc_expires'); 
        link_post_variable('comments'); 
// <<< END REGISTER_GLOBALS

        $this->cart();
      }
    }

================================================================================

.../catalog/includes/functions/general.php
------------------------------------------

Change the EXISTING function...

    tep_browser_detect()

...to read as follows :

////
// Returns the clients browser
  function tep_browser_detect($component) {
// >>> BEGIN REGISTER_GLOBALS
//    global $HTTP_USER_AGENT;

    return stristr($_SERVER['HTTP_USER_AGENT'], $component);
// <<< END REGISTER_GLOBALS
  }

                       -------------------------------------------

Add the following function to the very end of the general.php file (just before the last '?>')
(actually, it doesn't matter where in the file you put this)

NOTE: At present, these functions are not actually used (they ARE used in the admin
section though), so you can ignore this if you like. Later versions of the register_globals
patch might expect them to exist though

// >>> BEGIN REGISTER_GLOBALS
  // Work-around functions to allow disabling of register_globals in php.ini
  // These functions perform a similar operation as the 'link_session_variable'
  // function added to .../functions/sessions.php but for the GET, POST, etc
  // variables
  //
  // Parameters:
  // var_name - Name of session variable
  //
  // Returns:
  // None
  function link_get_variable($var_name)
  {
    // Map global to GET variable
    if (isset($_GET[$var_name]))
    {
      $GLOBALS[$var_name] =& $_GET[$var_name];
    }
  }

  function link_post_variable($var_name)
  {
    // Map global to POST variable
    if (isset($_POST[$var_name]))
    {
      $GLOBALS[$var_name] =& $_POST[$var_name];
    }
  }
// <<< END REGISTER_GLOBALS

================================================================================

.../catalog/includes/functions/gzip_compression.php
---------------------------------------------------

Change the EXISTING function...

    tep_check_gzip()

...to read as follows :

  function tep_check_gzip() {
// >>> BEGIN REGISTER_GLOBALS
//    global $HTTP_ACCEPT_ENCODING;
// <<< END REGISTER_GLOBALS
    if (headers_sent() || connection_aborted()) {
      return false;
    }

// >>> BEGIN REGISTER_GLOBALS
    if (strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'x-gzip') !== false) return 'x-gzip';

    if (strpos($_SERVER['HTTP_ACCEPT_ENCODING'],'gzip') !== false) return 'gzip';
// <<< END REGISTER_GLOBALS

    return false;
  }

================================================================================

.../catalog/includes/functions/sessions.php
-------------------------------------------

Change the EXISTING functions...

    tep_session_start()
    tep_session_register()
    tep_session_is_registered()
    tep_session_unregister

    (these four functions are grouped together in the unmodified code, but
     BE CAREFUL - don't just blindly cut and paste !)

...to read as follows :

  function tep_session_start() {
    global $HTTP_GET_VARS, $HTTP_POST_VARS, $HTTP_COOKIE_VARS;

    $sane_session_id = true;

    if (isset($HTTP_GET_VARS[tep_session_name()])) {
      if (preg_match('/^[a-zA-Z0-9]+$/', $HTTP_GET_VARS[tep_session_name()]) == false) {
        unset($HTTP_GET_VARS[tep_session_name()]);

        $sane_session_id = false;
      }
    } elseif (isset($HTTP_POST_VARS[tep_session_name()])) {
      if (preg_match('/^[a-zA-Z0-9]+$/', $HTTP_POST_VARS[tep_session_name()]) == false) {
        unset($HTTP_POST_VARS[tep_session_name()]);

        $sane_session_id = false;
      }
    } elseif (isset($HTTP_COOKIE_VARS[tep_session_name()])) {
      if (preg_match('/^[a-zA-Z0-9]+$/', $HTTP_COOKIE_VARS[tep_session_name()]) == false) {
        $session_data = session_get_cookie_params();

        setcookie(tep_session_name(), '', time()-42000, $session_data['path'], $session_data['domain']);

        $sane_session_id = false;
      }
    }

    if ($sane_session_id == false) {
      tep_redirect(tep_href_link(FILENAME_DEFAULT, '', 'NONSSL', false));
    }
 
// >>> BEGIN REGISTER_GLOBALS
    $success = session_start();

    // Work-around to allow disabling of register_globals - map all defined
    // session variables
    if ($success && count($_SESSION))
    {
      $session_keys = array_keys($_SESSION);
      foreach($session_keys as $variable)
      {
        link_session_variable($variable, true);
      }
    }

    return $success;
// <<< END REGISTER_GLOBALS
  }

  function tep_session_register($variable) {
    global $session_started;

// >>> BEGIN REGISTER_GLOBALS
    $success = false;

    if ($session_started == true) {
// -skip-   return session_register($variable);

      // Work-around to allow disabling of register_globals - map session variable
      link_session_variable($variable, true);
      $success = true;
    }

    return $success;
// <<< END SESSION_REGISTER
  }

  function tep_session_is_registered($variable) {
// >>> BEGIN REGISTER_GLOBALS
//    return session_is_registered($variable);
    return isset($_SESSION[$variable]);
// <<< END REGISTER_GLOBALS
  }

  function tep_session_unregister($variable) {
// >>> BEGIN REGISTER_GLOBALS
    // Work-around to allow disabling of register_gloabls - unmap session variable
    link_session_variable($variable, false);
    unset($_SESSION[$variable]);

//  return session_unregister($variable);
    return true;
// <<< END REGISTER_GLOBALS
  }

                        -------------------------------------------

Change the EXISTING functions...

    tep_session_close()
    tep_session_destroy()

    (these two functions are grouped together in the unmodified code, but
     BE CAREFUL - don't just blindly cut and paste !)

...to read as follows :

  function tep_session_close() {
// >>> BEGIN REGISTER_GLOBALS
    // Work-around to allow disabling of register_gloabls - unmap all defined
    // session variables
    if (count($_SESSION))
    {
      $session_keys = array_keys($_SESSION);
      foreach($session_keys as $variable)
      {
        link_session_variable($variable, false);
      }
    }

    if (PHP_VERSION >= '4.0.4') {
      session_write_close();
    } elseif (function_exists('session_close')) {
      session_close();
    }
// <<< END REGSITER_GLOBALS
  }

  function tep_session_destroy() {
// >>> BEGIN REGISTER_GLOBALS
    // Work-around to allow disabling of register_gloabls - unmap all defined
    // session variables
    if (count($_SESSION))
    {
      $session_keys = array_keys($_SESSION);
      foreach($session_keys as $variable)
      {
        link_session_variable($variable, false);
        unset($_SESSION[$variable]);
      }
    }
// <<< END REGISTER_GLOBALS
    return session_destroy();
  }

                        -------------------------------------------

Change the EXISTING function...

    tep_session_recreate() - technical note - I'm not sure this is necessary, but it won't hurt

...to read as follows :

  function tep_session_recreate() {
    if (PHP_VERSION >= 4.1) {
      $session_backup = $_SESSION;

      unset($_COOKIE[tep_session_name()]);

      tep_session_destroy();

      if (STORE_SESSIONS == 'mysql') {
        session_set_save_handler('_sess_open', '_sess_close', '_sess_read', '_sess_write', '_sess_destroy', '_sess_gc');
      }

// >>> BEGIN REGISTER_GLOBALS
//    tep_session_start();
//    $_SESSION = $session_backup;

      session_start();
      $_SESSION = $session_backup;

      // Work-around to allow disabling of register_globals - map all defined
      // session variables
      if (count($_SESSION))
      {
        $session_keys = array_keys($_SESSION);
        foreach($session_keys as $variable)
        {
          link_session_variable($variable, true);
        }
      }
// <<< END REGISTER_GLOBALS

      unset($session_backup);
    }
  }

                        -------------------------------------------

Add the following function to .../catalog/includes/functions/sessions.php  - it doesn't matter where
 - I added it just below the tep_session_unregister() function.

NOTE: There are two versions of this function here - unless you have a particular need to do
----  otherwise then I STRONGLY suggest you use the first version. The second version is really
      just for me as a debugging tool

VERSION 1 - USE THIS !!!
------------------------

// >>> BEGIN REGISTER_GLOBALS
  // Work-around function to allow disabling of register_globals in php.ini
  // This is pretty crude but it works. What it does is map session variables to
  // a corresponding global variable.
  // In this way, the main application code can continue to use the existing
  // global varaible names but they are actually redirected to the real session
  // variables
  //
  // If the global variable is already set with a value at the time of the mapping
  // then it is copied over to the real session variable before being mapped back
  // back again
  //
  // Parameters:
  // var_name - Name of session variable
  // map - true = map variable, false = unmap varaible
  //
  // Returns:
  // None
  function link_session_variable($var_name, $map)
  {
    if ($map)
    {
      // Map global to session variable. If the global variable is already set to some value
      // then its value overwrites the session varibale. I **THINK** this is correct behaviour
      if (isset($GLOBALS[$var_name]))
      {
        $_SESSION[$var_name] = $GLOBALS[$var_name];
      }

      $GLOBALS[$var_name] =& $_SESSION[$var_name];
    }
    else
   {
      // Unmap global from session variable (note that the global variable keeps the value of
      // the session variable. This should be unnecessary but it reflects the same behaviour
      // as having register_globals enabled, so in case the OSC code assumes this behaviour,
      // it is reproduced here
      $nothing = 0;
      $GLOBALS[$var_name] =& $nothing;
      unset($GLOBALS[$var_name]);
      $GLOBALS[$var_name] = $_SESSION[$var_name];
    }
  }
// <<< END REGISTER_GLOBALS

VERSION 2 - DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING AND HAVE A NEED FOR IT
------------------------------------------------------------------------------------

// >>> BEGIN REGISTER_GLOBALS
  // Work-around function to allow disabling of register_globals in php.ini
  // This is pretty crude but it works. What it does is map session variables to
  // a corresponding global variable.
  // In this way, the main application code can continue to use the existing
  // global varaible names but they are actually redirected to the real session
  // variables
  //
  // If the global variable is already set with a value at the time of the mapping
  // then it is copied over to the real session variable before being mapped back
  // back again
  //
  // Parameters:
  // var_name - Name of session variable
  // map - true = map variable, false = unmap varaible
  //
  // Returns:
  // None. An error message is printed if no global variable is available to map to
  // the supplied session variable
  function link_session_variable($var_name, $map)
  {
    $var_refs = array
    (
      // Customer details
      'customer_id' => true,
      'customer_first_name' => true,
      'customer_default_address_id' => true,
      'customer_country_id' => true,
      'customer_zone_id' => true,
      'customer_account_id' => true,

      // Shipping
      'sendto' => true,
      'shipping' => true,
      'comments' => true,

      // Payment
      'billto' => true,
      'payment' => true,

      // Shopping basket
      'cart' => true,
      'cartID' => true,

      // General
      'navigation' => true,
      'currency' => true,
      'language_id' => true,
      'languages_id' => true,
      'language' => true,
      'messageToStack' => true,
      'new_products_id_in_cart' => true,

      'SESSION_SSL_ID' => true,
      'SESSION_USER_AGENT' => true,
      'SESSION_IP_ADDRESS' => true
    );

    if(key_exists($var_name, $var_refs))
    {
      if ($map)
      {
        // Map global to session variable. If the global variable is already set to some value
        // then its value overwrites the session varibale. I **THINK** this is correct behaviour
        if (isset($GLOBALS[$var_name]))
        {
          $_SESSION[$var_name] = $GLOBALS[$var_name];
        }

        $GLOBALS[$var_name] =& $_SESSION[$var_name];
      }
      else
      {
        // Unmap global from session variable (note that the global variable keeps the value of
        // the session variable. This should be unnecessary but it reflects the same behaviour
        // as having register_globals enabled, so in case the OSC code assumes this behaviour,
        // it is reproduced here
        $nothing = 0;
        $GLOBALS[$var_name] =& $nothing;
        unset($GLOBALS[$var_name]);
        $GLOBALS[$var_name] = $_SESSION[$var_name];
      }
    }
    else
    {
      echo 'Fatal error: Session variable '.$var_name.' is not globally defined<br />';
    }
  }
// <<< END REGISTER_GLOBALS

================================================================================

.../catalog/includes/languages/english/password_forgotten.php
-------------------------------------------------------------

Change the EXISTING line...

define('EMAIL_PASSWORD_REMINDER_BODY', 'A new password was requested from ' . $REMOTE_ADDR . '.' . "\n\n" . 'Your new password to \'' . STORE_NAME . '\' is:' . "\n\n" . '   %s' . "\n\n");

...to read as follows :

// >>> BEGIN REGISTER_GLOBALS
define('EMAIL_PASSWORD_REMINDER_BODY', 'A new password was requested from ' . $_SERVER['REMOTE_ADDR'] . '.' . "\n\n" . 'Your new password to \'' . STORE_NAME . '\' is:' . "\n\n" . '   %s' . "\n\n");
// <<< END REGISTER_GLOBALS

                        -------------------------------------------

Repeat as required for your other language files

.../catalog/includes/languages/espanol/password_forgotten.php
.../catalog/includes/languages/german/password_forgotten.php

ie - replace...

  $REMOTE_ADDR
  
...with...

  $_SERVER['REMOTE_ADDR'] 

================================================================================
-eof-
