function system_handle_form_submit

6.x system.module system_handle_form_submit()
4.x system.module system_handle_form_submit()
5.x system.module system_handle_form_submit()

Intercepts form submissions from forms built with the form API.

File

modules/system/system.module, line 2093

Code

function system_handle_form_submit() {

  $callback = $_REQUEST ["callback"];

  $form_type = $_REQUEST ["form_type"];
  $form_include = $_REQUEST ["form_include"];

  $form_token = $_REQUEST ["form_token"];
  // Make sure the form_token is valid!
  if ($form_token != md5($callback . fp_token())) {
    die(t("Sorry, but you have encountered an error.  A form submission was flagged
          as possibly being an invalid or forged submission.  This may constitute a bug
          in the system.  Please report this error to your Systems Administrator."));
  }

  if ($form_include != "") {
    // This is a file we need to include in order to complete the submission process.

    // We will also make sure that we only allow certain file extensions to be included.
    $allowed_ext = array(
      "php",
      "inc",
      "class",
      "module",
    );

    $temp = explode(".", $form_include);
    $test_ext = trim($temp [count($temp) - 1]);

    if (!in_array($test_ext, $allowed_ext)) {
      fp_add_message(t("Include file type (%ext) not allowed in form submission.", array("%ext" => $test_ext)), "error");
      fp_goto("<front>");
      return;
    }

    // We need to make sure, before we include this file, that it is something only available from within the main FlightPath directory.
    $absolute_path = realpath($form_include);
    $absolute_path = str_replace("\\", "/", $absolute_path);

    // In order for us to proceed, the $absolute_path must BEGIN with our base FlightPath installation directory.  
    $file_system_path = $GLOBALS ['fp_system_settings']['file_system_path'];


    if (substr($absolute_path, 0, strlen($file_system_path)) != $file_system_path) {
      fp_add_message(t("Include file in form submission is outside of the FlightPath installation directory.
                          <br>FlightPath directory path: %fsp
                          <br>Include file path: %ap", array("%fsp" => $file_system_path, "%ap" => $absolute_path)), "error");
      fp_goto("<front>");
      return;
    }


    include_once ($form_include);
  }


  // We need to make sure the user has permission to submit this form!
  $form_path = $_REQUEST ["form_path"];
  // Check the menu router table for whatever the permissions were for this
  // path, if any.
  if ($form_path != "") {
    $router_item = menu_get_item($form_path);
    if (!menu_check_user_access($router_item)) {
      // The user does NOT have access to submit this form!  The fact that
      // it has made it this far means this may be some sort of hacking attempt.
      die(t("Sorry, but you have encountered an error.  A form submission was flagged
          as possibly being an invalid or having insufficient permissions to submit.  
          This may constitute a bug in the system.  
          Please report this error to your Systems Administrator."));

    }
  }

  // Let's get our set of allowed values, by looking at the original form,
  // and grab what's in the POST which matches the name.

  $values = array();
  $safe_values = array(); // will be the same as $values, but anything of type password will not be included.

  if (function_exists($callback)) {

    // Get any params for the callback, or, an empty array.    
    $form_params = @unserialize(base64_decode($_REQUEST ['form_params']));
    if (!$form_params) {
      $form_params = array();
    }
    // Actually get the form now.    
    $form = fp_get_form($callback, $form_params);
    foreach ($form as $name => $element) {

      // Save to our $values array, but we don't care about markup.
      if (@$element ["type"] != "" && @$element ["type"] != "markup") {
        $values [$name] = @$_POST [$name];

        // Save to save_values, too, if this is not a password field.
        if (@$element ["type"] != "password") {
          $safe_values [$name] = @$_POST [$name];
        }

      }
      // Do we need to alter the value from the POST?

      // If this element is a cfieldset, it may contain other elements.  We should get
      // those values too.
      if (isset($element ["elements"])) {
        foreach ($element ["elements"] as $k => $v) {
          foreach ($element ["elements"][$k] as $cname => $celement) {
            // Save to our $values array, but we don't care about markup.
            if (@$celement ["type"] != "" && @$celement ["type"] != "markup") {
              $values [$cname] = @$_POST [$cname];

              // Save to save_values, too, if this is not a password field.
              if (@$celement ["type"] != "password") {
                $safe_values [$cname] = @$_POST [$cname];
              }


            }
          }
        }
      }


      // If this is a checkbox, and we have any value in the POST, it should
      // be saved as boolean TRUE
      if (isset($element ["type"]) && $element ["type"] == "checkbox") {
        if (isset($_POST [$name]) && $_POST [$name] === "1") {
          $values [$name] = TRUE;
        }
      }

    }
  }

  // Does the form have any defined submit_handler's?  If not, let's assign it the
  // default of callback_submit().    
  $submit_handlers = $form ["#submit_handlers"];
  if (!is_array($submit_handlers)) {
    $submit_handlers = array();
  }

  // If the submit_handlers is empty, then add our default submit handler.  We don't
  // want to do this if the user went out of their way to enter a different handler.
  if (count($submit_handlers) == 0) {
    array_push($submit_handlers, $callback . "_submit");
  }

  // Does the form have any defined validate_handler's?  This works exactly like the submit handler.
  $validate_handlers = $form ["#validate_handlers"];
  if (!is_array($validate_handlers)) {
    $validate_handlers = array();
  }

  if (count($validate_handlers) == 0) {
    array_push($validate_handlers, $callback . "_validate");
  }

  // Let's store our values in the SESSION in case we need them later on.
  // But only if this is NOT a system_settings form!
  if ($form_type != "system_settings") {

    // Do not store any "password" field, for security, so it isn't stored
    // in the server's session file in plain text.
    // For this reason we will use the $safe_values array we created earlier.    

    $_SESSION ["fp_form_submissions"][$callback]["values"] = $safe_values;
  }

  $form_state = array("values" => $values, "POST" => $_POST);

  // Let's pass this through our default form validator (mainly to check for required fields
  // which do not have values entered)
  form_basic_validate($form, $form_state);

  if (!form_has_errors()) {
    // Let's now pass it through all of our custom validators, if there are any.
    foreach ($validate_handlers as $validate_callback) {
      if (function_exists($validate_callback)) {

        call_user_func_array($validate_callback, array(&$form, &$form_state));
      }
    }
  }

  if (!form_has_errors()) {
    // No errors from the validate, so let's continue.

    // Is this a "system settings" form, or a normal form?
    if ($form_type == "system_settings") {
      // This is system settings, so let's save all of our values to the variables table.
      // Write our values array to our variable table.
      foreach ($form_state ["values"] as $name => $val) {
        variable_set($name, $val);
      }

      fp_add_message("Settings saved successfully.");

    }

    // Let's go through the form's submit handlers now.
    foreach ($submit_handlers as $submit_callback) {
      if (function_exists($submit_callback)) {
        //call_user_func($submit_callback, $form, &$form_state);

        call_user_func_array($submit_callback, array(&$form, &$form_state));

      }
    }



  }

  // Figure out where we are supposed to redirect the user.
  $redirect_path = $redirect_query = "";

  if (isset($form ["#redirect"]) && is_array($form ["#redirect"])) {
    $redirect_path = $form ["#redirect"]["path"];
    $redirect_query = $form ["#redirect"]["query"];
  }
  else {
    $redirect_path = @$_REQUEST ["default_redirect_path"];
    $redirect_query = @$_REQUEST ["default_redirect_query"];


    // To help prevent directory traversal attacks, the redirect_path cannot contain periods (.) and semi-colons, and other trouble characters
    $redirect_path = str_replace(".", "", $redirect_path);
    $redirect_path = str_replace(";", "", $redirect_path);
    $redirect_path = str_replace("'", "", $redirect_path);
    $redirect_path = str_replace('"', "", $redirect_path);
    $redirect_path = str_replace(' ', "", $redirect_path);


  }

  // If there is a Batch process we need to do, do it here instead of the fp_goto.
  if (isset($_SESSION ["fp_batch_id"]) && function_exists("batch_menu")) {
    $batch_id = $_SESSION ["fp_batch_id"];
    unset($_SESSION ["fp_batch_id"]);
    batch_start_batch_from_form_submit($batch_id, $redirect_path, $redirect_query);
    return;
  }
  else if (isset($_SESSION ["fp_batch_id"]) && !function_exists("batch_menu")) {
    // We requested a batch action, but the batch module is not installed.
    fp_add_message(t("A batch process was attempted, but it appears that the Batch module is not enabled.  Please contact your FlightPath administrator."), "error");
    unset($_SESSION ["fp_batch_id"]);
  }

  // Okay, go back to where we were!  
  fp_goto($redirect_path, $redirect_query);

}