/**
  * Processes config variables passed via an HTML form
  *
  * @version 1.0
  * @since 1.0
  *
  * @param array $post | HTML form array
  * @return int | Exception on failure. Number of rows changed on success.
  */
 public function processHTMLForm($post)
 {
     if (empty($post['key_names'])) {
         throw new FOX_exception(array('numeric' => 1, 'text' => "No key names posted with form", 'data' => $post, 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => null));
     }
     $san = new FOX_sanitize();
     // Explode fields array into individual key names
     $options = explode(',', stripslashes($post['key_names']));
     // Convert the encoded full name into its corresponding $tree, $branch,
     // and $key, then add the group to the query array
     // ====================================================================
     $query_keys = array();
     foreach ($options as $option) {
         $full_name = explode($this->key_delimiter, $option);
         // Process the raw form strings into proper key names
         $raw_plugin = trim($full_name[0]);
         $raw_tree = trim($full_name[1]);
         $raw_branch = trim($full_name[2]);
         $raw_key = trim($full_name[3]);
         // Passed by reference
         $plugin_valid = null;
         $tree_valid = null;
         $branch_valid = null;
         $key_valid = null;
         $plugin_error = null;
         $tree_error = null;
         $branch_error = null;
         $key_error = null;
         try {
             $plugin = $san->keyName($raw_plugin, null, $plugin_valid, $plugin_error);
             $tree = $san->keyName($raw_tree, null, $tree_valid, $tree_error);
             $branch = $san->keyName($raw_branch, null, $branch_valid, $branch_error);
             $key = $san->keyName($raw_key, null, $key_valid, $key_error);
         } catch (FOX_exception $child) {
             throw new FOX_exception(array('numeric' => 2, 'text' => "Error in sanitizer function", 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child));
         }
         if (!$plugin_valid) {
             throw new FOX_exception(array('numeric' => 3, 'text' => "Called with invalid plugin name", 'data' => array('raw_tree' => $raw_plugin, 'san_error' => $plugin_error), 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => null));
         } elseif (!$tree_valid) {
             throw new FOX_exception(array('numeric' => 4, 'text' => "Called with invalid tree name", 'data' => array('raw_tree' => $raw_tree, 'san_error' => $tree_error), 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => null));
         } elseif (!$branch_valid) {
             throw new FOX_exception(array('numeric' => 5, 'text' => "Called with invalid branch name", 'data' => array('raw_branch' => $raw_branch, 'san_error' => $branch_error), 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => null));
         } elseif (!$key_valid) {
             throw new FOX_exception(array('numeric' => 6, 'text' => "Called with invalid node name", 'data' => array('raw_key' => $raw_key, 'san_error' => $key_error), 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => null));
         }
         $query_keys[$plugin][$tree][$branch][$key] = true;
         unset($option, $plugin, $raw_plugin, $tree, $raw_tree, $branch, $raw_branch, $key, $raw_key);
         unset($plugin_error, $tree_error, $branch_error, $key_error, $plugin_valid, $tree_valid, $branch_valid, $key_valid);
     }
     if (count(array_keys($query_keys)) > 1) {
         throw new FOX_exception(array('numeric' => 7, 'text' => "Attempting to set nodes for multiple plugins", 'data' => array_keys($query_keys), 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => null));
     }
     $get_ctrl = array('validate' => false, 'q_mode' => 'trie', 'r_mode' => 'trie', 'trap_*' => true);
     try {
         // We do not use getMulti's $valid flag to trap nonexistent keys
         // because we want to throw an error listing the key names
         $current_keys = parent::getMulti($query_keys, $get_ctrl);
     } catch (FOX_exception $child) {
         throw new FOX_exception(array('numeric' => 8, 'text' => "Error calling parent::getMulti()", 'data' => $query_keys, 'file' => __FILE__, 'class' => __CLASS__, 'function' => __FUNCTION__, 'line' => __LINE__, 'child' => $child));
     }
     // Iterate through all of the requested keys, cast the submitted form
     // data for each key to the format specified in the key's db entry
     // ====================================================================
     $rows_changed = 0;
     $invalid_nodes = array();
     $update_keys = array();
     foreach ($query_keys as $plugin => $trees) {
         foreach ($trees as $tree => $branches) {
             foreach ($branches as $branch => $nodes) {
                 foreach ($nodes as $node => $fake_var) {
                     if (!FOX_sUtil::keyExists($node, $current_keys[$plugin][$tree][$branch])) {
                         $invalid_nodes[] = "P: {$plugin} T: {$tree} B: {$branch} N: {$node}";
                         continue;
                     }
                     $filter = $current_keys[$plugin][$tree][$branch][$node]["filter"];
                     $filter_ctrl = $current_keys[$plugin][$tree][$branch][$node]["filter_ctrl"];
                     // Remove any escaping PHP has added to the posted form value
                     $post_key = $plugin . $this->key_delimiter . $tree . $this->key_delimiter;
                     $post_key .= $branch . $this->key_delimiter . $node;
                     $post[$post_key] = FOX_sUtil::formVal($post[$post_key]);
                     // Run key value through the specified filter
                     // =====================================================
                     $filter_valid = null;
                     $filter_error = null;
                     // Passed by reference
                     try {
                         $new_val = $san->{$filter}($post[$post_key], $filter_ctrl, $filter_valid, $filter_error);
                     } catch (FOX_exception $child) {
                         throw new FOX_exception(array('numeric' => 9, 'text' => "Error in filter function", 'data' => array('filter' => $filter, 'val' => $post[$post_key], 'ctrl' => $ctrl, 'filter_valid' => $filter_valid, 'filter_error' => $filter_error), 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child));
                     }
                     if (!$filter_valid) {
                         throw new FOX_exception(array('numeric' => 10, 'text' => "Filter function reports value data isn't valid", 'data' => array('filter' => $filter, 'val' => $post[$post_key], 'ctrl' => $ctrl, 'filter_valid' => $filter_valid, 'filter_error' => $filter_error), 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => null));
                     }
                     // If the new value doesn't match the stored value, update the key
                     // (using === because null == int )
                     // ====================================================================
                     if ($new_val !== $current_keys[$plugin][$tree][$branch][$node]["val"]) {
                         $update_keys[$plugin][$tree][$branch][$node] = array('filter' => $filter, 'filter_ctrl' => $filter_ctrl, 'val' => $new_val);
                     }
                 }
                 // ENDOF: foreach($nodes as $node => $fake_var)
                 unset($node, $fake_var);
             }
             // ENDOF: foreach($branches as $branch => $nodes)
             unset($branch, $nodes);
         }
         // ENDOF: foreach($trees as $tree => $branches)
         unset($tree, $branches);
     }
     // ENDOF: foreach($query_keys as $plugin => $trees)
     unset($plugin, $trees);
     if ($invalid_nodes) {
         throw new FOX_exception(array('numeric' => 11, 'text' => "Trying to set one or more nonexistent nodes", 'data' => $invalid_nodes, 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => null));
     }
     if ($update_keys) {
         $set_ctrl = array('validate' => false, 'mode' => 'trie');
         try {
             $rows_changed = parent::setMulti($update_keys, $set_ctrl);
         } catch (FOX_exception $child) {
             throw new FOX_exception(array('numeric' => 12, 'text' => "Error in parent::setMulti()", 'data' => array('update_keys' => $update_keys, 'set_ctrl' => $set_ctrl), 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child));
         }
     }
     return (int) $rows_changed;
 }
 /**
  * Processes config variables passed via an HTML form
  *
  * @version 1.0
  * @since 1.0
  *
  * @param array $post | HTML form array
  * @return bool | Exception on failure. True on success.
  */
 public function processHTMLForm($post)
 {
     if (empty($post['key_names'])) {
         throw new FOX_exception(array('numeric' => 1, 'text' => "No key names posted with form", 'data' => $post, 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => null));
     }
     $san = new FOX_sanitize();
     // Explode fields array into individual key names
     $options = explode(',', stripslashes($post['key_names']));
     // Sanitize keys. Loft key-value pairs into a multidimensional array
     // ====================================================================
     $processed_keys = array();
     foreach ($options as $option) {
         $full_name = explode($this->key_delimiter, $option);
         // Process the raw form strings into proper key names
         $raw_tree = trim($full_name[0]);
         $raw_branch = trim($full_name[1]);
         $raw_key = trim($full_name[2]);
         // Passed by reference
         $tree_valid = null;
         $branch_valid = null;
         $key_valid = null;
         $tree_error = null;
         $branch_error = null;
         $key_error = null;
         try {
             $tree = $san->keyName($raw_tree, null, $tree_valid, $tree_error);
             $branch = $san->keyName($raw_branch, null, $branch_valid, $branch_error);
             $key = $san->keyName($raw_key, null, $key_valid, $key_error);
         } catch (FOX_exception $child) {
             throw new FOX_exception(array('numeric' => 2, 'text' => "Error in sanitizer function", 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child));
         }
         if (!$tree_valid) {
             throw new FOX_exception(array('numeric' => 3, 'text' => "Called with invalid tree name", 'data' => array('raw_tree' => $raw_tree, 'san_error' => $tree_error), 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => null));
         } elseif (!$branch_valid) {
             throw new FOX_exception(array('numeric' => 4, 'text' => "Called with invalid branch name", 'data' => array('raw_branch' => $raw_branch, 'san_error' => $branch_error), 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => null));
         } elseif (!$key_valid) {
             throw new FOX_exception(array('numeric' => 5, 'text' => "Called with invalid key name", 'data' => array('raw_tree' => $raw_tree, 'raw_branch' => $raw_branch, 'raw_key' => $raw_key, 'san_error' => $key_error), 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => null));
         }
         // Manually generate the $post array keyname to avoid escaping added by PHP
         $post_key = $tree . $this->key_delimiter . $branch . $this->key_delimiter . $key;
         $processed_keys[$tree][$branch][$key] = FOX_sUtil::formVal($post[$post_key]);
         unset($full_name, $tree, $raw_tree, $branch, $raw_branch, $key, $raw_key);
         unset($tree_error, $branch_error, $key_error, $tree_valid, $branch_valid, $key_valid);
     }
     unset($option);
     // Assemble the processed keys into the right format for the
     // the database classes
     // ===============================================================
     $target_data = array();
     if ($processed_keys["target"]["key"]["location"] == "page") {
         $target_data["location"] = (string) $processed_keys["target"]["key"]["location"];
         $target_data["module_id"] = (int) $processed_keys["target"]["key"]["module_id"];
         $target_data["target"] = (int) $processed_keys["target"]["key"]["page_id"];
     } else {
         $target_data["location"] = (string) $processed_keys["target"]["key"]["location"];
         $target_data["module_id"] = (int) $processed_keys["target"]["key"]["module_id"];
         $target_data["target"] = (string) $processed_keys["target"]["key"]["slug"];
         $target_data["tab_title"] = (string) $processed_keys["target"]["key"]["tab_title"];
         $target_data["tab_position"] = (int) $processed_keys["target"]["key"]["tab_position"];
     }
     $policy_data = array();
     // Loft the keys into a heirarchical array and decode JSON-encoded fields
     // ======================================================================
     foreach ($processed_keys["policy"] as $zone => $rules) {
         foreach ($rules as $rule => $rule_data) {
             $rule_decoded = json_decode($rule_data, true);
             if (!empty($rule_decoded)) {
                 foreach ($rule_decoded as $key_type => $key_ids) {
                     foreach ($key_ids as $key_id => $key_data) {
                         // Since we're not handling $ctrl info for keys yet, we need to
                         // manually set a value for the key.
                         $policy_data[$zone][$rule][$key_type][$key_id] = true;
                     }
                     unset($key_id, $key_data);
                 }
                 unset($key_type, $key_ids);
             }
         }
         unset($rule, $rule_data, $rule_decoded);
     }
     unset($zone, $rules);
     // Update the target and policy classes
     // ===============================================================
     try {
         $this->target_class->setTarget($target_data);
     } catch (FOX_exception $child) {
         throw new FOX_exception(array('numeric' => 6, 'text' => "Error updating target data", 'data' => $target_data, 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child));
     }
     try {
         $this->policy_class->replaceL5((int) $target_data["module_id"], $policy_data);
     } catch (FOX_exception $child) {
         throw new FOX_exception(array('numeric' => 7, 'text' => "Error updating policy data", 'data' => array('module_id' => $target_data["module_id"], 'policy_data' => $policy_data), 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child));
     }
     return true;
 }
 /**
  * Gets the slug of the currently selected module tab at the admin screen
  *
  * @version 1.0
  * @since 1.0
  * @return string | Exception on failure. Module tab slug as string on success.
  */
 public function getSelectedTab()
 {
     if (!$this->init) {
         throw new FOX_exception(array('numeric' => 0, 'text' => "Descendent class must call init() before using class methods", 'file' => __FILE__, 'class' => __CLASS__, 'function' => __FUNCTION__, 'line' => __LINE__, 'child' => null));
     }
     $san = new FOX_sanitize();
     try {
         $result = $san->slug($_GET['tab'], $ctrl = null);
     } catch (RAD_Exception $child) {
         throw new FOX_exception(array('numeric' => 1, 'text' => "Sanitizer function returned an error", 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child));
     }
     return $result;
 }