$debug = false; // enable "debug mode" for this script class ouldp { public $config; public function __construct($config) { $this->config = $config; } private function createArrayXML($array, &$xml) { $structElem = $xml->addChild('struct'); foreach ($array as $key => $val) { $memberElem = $structElem->addChild('member'); $memberElem->addChild('name', $key); $memberValueElem = $memberElem->addChild('value'); if (is_array($val)) { $this->createArrayXML($val, $memberValueElem); } else { $memberValueElem->addChild('string', $val); } } } public function send($method, $param) { global $debug; $curlError = ""; $result = array("active" => false, "message" => "", "data" => ""); $gen_usr_err_ms = "The given file(s) do not match the criteria. Please try again."; foreach ($_FILES as $key => $file) { // no file was uploaded, completely ignore it if ($file["error"] != UPLOAD_ERR_NO_FILE) { // checking to see if the given files is not ok, if not ok return and stop processing if ($file["error"] != UPLOAD_ERR_OK) { return array("active" => false, "message" => ("Faultcode: 100" . $file["error"]), "data" => $gen_usr_err_ms); } // so there is actually a file uploaded with no errors, lets process it. // have to split and end the filename in two seperate operations to avoid php notice: Only variables should be passed by reference in $temp_filename = explode("/", $file["name"]); $temp_actual_filename = end($temp_filename); // conditional checkes on the filename and filesize lengths $length_passes = ((1 <= strlen($temp_actual_filename)) && (strlen($temp_actual_filename) <= 256)); $filesize_pass = ((1 <= $file["size"]) && ($file["size"] <= 26214400)); // make sure the name is set and length less than 256 characters, // the bytes are greater than 0 and less than 25mb and file didn't error if ($length_passes && $filesize_pass) { $cur_file = @fopen($file["tmp_name"], "rb"); if ($cur_file) { $param[2][$key] = array( 'name' => $file["name"], 'type' => $file["type"], 'size' => $file["size"], 'data' => base64_encode(fread($cur_file, $file["size"])) ); fclose($cur_file); } else { return array("active" => false, "message" => "Faultcode: 1010", "data" => $gen_usr_err_ms); } } else { return array("active" => false, "message" => "Faultcode: 1011", "data" => $gen_usr_err_ms); } } } //SimpleXML to turn form data into xmlrpc (replacing xmlrpc_encode_request) $output_options = ['encoding' => 'utf-8', 'escaping' => 'markup', 'verbosity' => 'no_white_space']; //create the XML-RPC request using SimpleXML (encode) $request = new SimpleXMLElement(''); $request->addChild('methodName', $method); $params = $request->addChild('params'); foreach ($param as $value) { $param = $params->addChild('param'); $valueElem = $param->addChild('value'); if (is_array($value)) { $this->createArrayXML($value, $valueElem); } else { $valueElem->addChild('string', $value); } } // add attributes to the methodCall element $request->addAttribute('encoding', $output_options['encoding']); $request->addAttribute('escaping', $output_options['escaping']); $request->addAttribute('verbosity', $output_options['verbosity']); $request = $request->asXML(); if ($request) { //Handle encoding $request = preg_replace('/ /', '', $request); $port = $this->config['ssm_port'] ? ':' . $this->config['ssm_port'] : ''; $path = $this->config['ssm_path'] ? $this->config['ssm_path'] : ''; $url = $this->config['ssm_host'] . $port . $path; // using curl to post the data to the SSM this is a change to the default // this is a more secure way than allowing url_open when the SSM is on a different server than the website $ch = curl_init($url); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: text/xml')); curl_setopt($ch, CURLOPT_POSTFIELDS, $request); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $ssmResponse = curl_exec($ch); // preserve curl error if present if (curl_error($ch)) { $curlError = curl_error($ch); } curl_close($ch); //decode ssmResponse from curl method // Convert the XML object to an array $xml = simplexml_load_string($ssmResponse); $result = json_decode(json_encode($xml), true); $result = $result['params']['param']['value']['struct']['member']; // Create the final array function parseArray($inputArray) { $outputArray = array(); foreach ($inputArray as $item) { $name = $item['name']; switch (key($item['value'])) { case 'boolean': $outputArray[$name] = $item['value']['boolean'] == '1' ? true : false; break; case 'string': $outputArray[$name] = $item['value']['string']; break; case 'array': $outputArray[$name] = $item['value']; break; } } return $outputArray; } $value = parseArray($result); if (isset($value['faultCode'])) { $result['message'] = "Faultcode : " . $value['faultCode']; $result['data'] = $value['faultString']; } elseif (isset($value['success'])) { if ($value['success'] == true) { //POST: Form submisson correct $result['active'] = $value['success']; $result['message'] = $value['message']; } else { //POST: Submission is not active. $result['active'] = $value['success']; $result['message'] = $value['message']; $error_values = $value['errors']['array']['data']['value']; // Check if there are any error values if (!empty($error_values)) { // If there's only one error value, parse it directly without loop if (count($error_values) === 1) { $result['data'][] = parseArray($error_values['struct']['member']); } else { // If there is more than one error value, parse each one foreach ($error_values as $error_value) { $result['data'][] = parseArray($error_value['struct']['member']); } } } } } elseif (isset($value['active'])) { //GET: Form is active. //Active is true if ($value['active'] == true) { $result['active'] = true; $result['message'] = "form ID"; $result['data'] = $value['formid']; } else { //GET: Form is inactive. $result['message'] = $value['message']; } } elseif (isset($value['errors'])) { //POST: Incorrect data provided $result['active'] = true; $result['message'] = "errors"; $result['data'] = $value['errors']; } elseif ($curlError != "") { //Curl encountered an error. $result['message'] = "Faultcode : Curl Error"; $result['data'] = "An error with curl contacting the server. Please enable debug mode for more info."; if ($debug) { $result['data'] = $curlError; } } else { //Form encountered an error. $result['message'] = "Faultcode : unknown"; $result['data'] = "An unknown error when contacting the server. Please Check the logs."; } } else { $result["message"] = "Faultcode: 999"; $result["data"] = "The form failed to submit properly, please contact site administrator."; } return $result; } public function validateCaptcha() { $response = isset($_POST['g-recaptcha-response']) ? $_POST['g-recaptcha-response'] : ''; if ($response == '') { // captcha validation failed return false; } $url = 'https://www.google.com/recaptcha/api/siteverify'; $secret = $this->config['captcha_secret']; $remoteip = $_SERVER['REMOTE_ADDR']; $params = array( 'secret' => $secret, 'response' => $response, 'remoteip' => $remoteip ); $ch = curl_init($url); curl_setopt($ch, CURLOPT_POST, true); // curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: text/xml')); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); curl_close($ch); $response = json_decode($response, true); if (isset($response['success']) && $response['success'] == true) { // captcha validation passed return true; } else { // captcha validation failed return false; } } }