<?
/** 
 * FormHandler basic script.
 *
 * This is the script that is actually called and does the initiation of
 * the basic modules and classes.
 *
 * @package   FormHandler
 * @version   2.1.1 Development
 * @author    Herman Suijs
 * @project   FormHandler PHP Mailscript
 * (http://formhandler.sourceforge.net)
 */

// The action-levels are necessary, because otherwise the deletion of
// options configured in the form will be done AFTER the mail is sent.
/* This is the main file of the form-handler package.
 */
// Check for a different config-file option from the form and load that
// configuration file. Otherwise use the default configuration.
// This is the only option in a form that is not handled by a module.
$starttime=time();
if (
$config_file) {
  require_once(
"$config_file");
}
else {
  require_once(
"configfile.inc.php");
}

if (
USE_KEYFILE&&file_exists(KEY_FILE)) {
  if (empty(
$key)) {
    require_once(
ERROR_SPAM_SETUP);
    exit;
  }
  
$key_file file(KEY_FILE);
  if (!
in_array($key,$key_file)) {
    require_once(
ERROR_SPAM); // spam or server too busy
    
exit;
  }
  if (
$starttime-filectime(KEY_FILE)>KEY_REFRESH) {
    if (!
delete(KEY_FILE)) {
      require_once(
ERROR_KEYFILE_WRONGPERMISSION);
      exit;
    }
  }
  
/*
  $fd=fopen("a",COUNT_FILE);
  fwrite($fd,"1");
  fclose($fd);
  */
/* if (file_exists(KEY_FILE)) */


// Global array of modules that are loaded and can be used.
$modules = array(); // Always globally addressed
$wrap_up_mods = array(); // Modules that have a wrap_up function.
$debug false// for checking existence
$error false;
$tmp_debug_array = array();
$runlevel 0;
$formHandler false;


/**
 * function createSortedArray
 *
 * This function Sorts all the dynamically loaded modules, do they will be
 * executed in the runlevel they specified.
 *
 * @param   modules: array of module-objects
 * @return  sorted_modules: sorted array of module-objects
 */
function createSortedArray($modules) {
  global 
$debug;
  
$sorted_modules = array();
  
reset($modules);
  while (list(
$name,$module) = each($modules)) {
    
$execlevel $module->execlevel();
    if (isset(
$execlevel)) {
      if (
$sorted_modules[$execlevel]) {
    
$sorted_modules[$execlevel] .= ":" $name;
      } else {
    
$sorted_modules[$execlevel] = $name;
      }
    } 
// end if isset
  
}
  
ksort($sorted_modules);
  
reset($sorted_modules);
  while (list(
$name,$val) = each($sorted_modules)) {
    
//$debug->add_message("$name - $val","createSortedArray");
    
$debug->add(6,"FH_createSortedArray","%s - %s",$name,$val);
  }
  
reset($sorted_modules);
  return 
$sorted_modules;
}

/**
 * Function to dynamically load in a module
 * 
 * This function can be called from within the application to add another
 * module. The added module should be in a higher runlevel
 *
 * @param   module_file: the file that contains the module-code
 * @param   name: the name to be used in the modules-array
 * @param   init: true when called in initiation process (not all modules
 * available)
 * @return  message: a debug message to display (can be called before debug
 * messaging module exists)
 */
function addModule($module_file,$name,$init=false) {
  global 
$runlevel,$modules;
  
// Module should create itself and a constant with name
  
$module_file ereg("php$",$module_file) ? $module_file $module_file MOD_EXT;
  
$module_dir ereg("inc.php$",$module_file) ? INCLUDE_DIR MODULES_DIR;
  require_once(
$module_dir."/$module_file");
  
// Debug-message before debug-object exists
  
$message="Module $name ($module_file) added.";
  
//echo "<br>";
  
  // Adjust runlevel if it is too small for a module that has been created
  
if (isset($modules[$name])) {
    
$exec $modules[$name]->execlevel();
    if (!empty(
$exec)&&$exec<$runlevel*STEP_EXECLEVEL) {
      
// Execute at first in the next runlevel run
      
$modules[$name]->set_execlevel(($runlevel+1)*STEP_EXECLEVEL);
    } 
// end if empty
  
// end if isset
  
return $message;
}

/**
 * Function to check for false options
 * 
 * This function checks if the 'false' string is used.
 *
 * @param   option: the option to check
 * @return  the boolean value
 */
function is_true($option) {
  if (
eregi(_FALSE,$option)) {
    return 
false;
  } else {
    return 
true;
  }
}

/**
 * Function to replace serialize
 *
 * @param   string or array
 * @return  return_string: value serialized in a string
 */
function fh_serialize($array) {
  if (
is_array($array)) {
    
$return_string "<ul>\n";
    while (list(
$name,$value) = each($array)) {
      if (
is_array($value)) {
    
$return_string .= "<li>$name: "+fh_serialize($value)+"\n";
      } else {
    
$return_string .= "<li>$name: $value\n";
      }
    }
    
$return_string .= "</ul>\n";
  } else {
    
$return_string $array;
  }
  return 
$return_string;
}

/****************************************************************/

/*
 * Start the actual script
 */
// Load in the (pre) configured modules, these are defined in
// configfile.inc.php
reset($load_modules);
while(list(
$name,$module_file) = each($load_modules)) {
  
$message addModule($module_file,$name,true);
  
// Debugmessage
  
if ($debug) {
    
//$debug->add_message($message,"Init");
    
$debug->add(-1,"FH_Init",$message);
  } else {
    
// Store in temp-array if debug object doesn't exist
    
$tmp_debug_array[$name] = $message;
  }

  
// Make reporting objects globally addressable
  
switch ($name) {
    case 
MES_DEBUG :
      
$debug = &$modules[MES_DEBUG];
      
// Add the debug-messages so far.
      
$debug->message_array($tmp_debug_array);
      unset(
$tmp_debug_array); // Destroy the variable
      
break;
    case 
MES_ERROR :
      
$error = &$modules[MES_ERROR];
      break;
  }

}
// Remark
checkoutput();


/**
 * Global addressable exit function
 *
 *  This should call functions from different modules and debug and error
 */
function exit_fh() {
  global 
$modules,$wrap_up_mods,$debug,$starttime,$info;
  
//$debug->add_message("Exit function called","exit_fh function",-1);
  
$debug->add(-1,"FH_exit_fh function","Exit function called");
  
$endtime=time();
  
$time=$endtime-$starttime;
  
$debug->add(-1,"FH_exit_fh function","Execution time: %s sec",$time);
  
reset($wrap_up_mods);
  while (list(
$module_name,$func) = each($wrap_up_mods)) {
    
//echo "<hr>Exit function ($func) for module $module_name ($modules[$module_name]->name)called<br>\n";
    
$modules[$module_name]->$func();
  }
  
//$time=time()-$starttime;
  //echo "Execution time: $time sec";
  
checkoutput();
  exit;
}

// The actual functionality of the script is dynamically loaded in as a
// module. The formHandler variable gives all other modules a reference to
// that module.
$formHandler =& $modules[FORMHANDLER];
//echo serialize($formHandler);
/* is done in constructor
$formHandler->set_html(true,ERROR_CONTENT);
$formHandler->set_title("Error",ERROR_CONTENT);
$formHandler->set_html(true,DEBUG_CONTENT);
$formHandler->set_header("<h2>Debug</h2>",DEBUG_CONTENT);
$formHandler->set_footer("",DEBUG_CONTENT);
*/

// Start runlevels
for($runlevel=0;$runlevel<MAX_STEPS;$runlevel++) {
  
$startrltime=time();
  
$formHandler->runlevel($runlevel);
  
$rltime=time()-$startrltime;
  
$debug->add(-1,"FH Runlevel steps","Execution time runlevel %s: %s sec",$runlevel,$rltime);
}
// call the exit function to properly wrap-up everything.
exit_fh();