Send Form value to two destinations - php

My question is I have a form that I want to submit its values to two locations, 1 would be to my networks database and another to a vicidials server that accepts this api, what would be my approach on doing this, I was thinking of php redirect using header() after inserting to database, isn't it messy that way? Is there any other way of doing this?
Form -> Database -> This apilink
http://serverip/vicidial/non_agent_api.php?phone_number=123456&first_name=John&last_name=Smith&address1=7153+Marbella+Unit+401&city=Cape+Canaveral&state=FL&postal_code=329200000&custom_fields=Y&birth_date=12-25-2017&duplicate_check=DUPCAMP

You can make two functions, one to save the submitted data to the database and one to submit it to the API.
function handleForm()
{
$data = [
'phone_number' => $_POST['phone_number'],
'first_name' => $_POST['first_name'],
// etc ...
];
$inserted = insertToDb($data);
if ($inserted) {
$api_response = submitToApi($data);
}
}
function insertToDb($data)
{
$inserted = false;
// do stuff to insert data to database
if (/**stuff went good**/) {
$inserted = true;
}
return $inserted;
}
function submitToApi($data)
{
$query_string = http_build_query($data);
$url = 'http://serverip/vicidial/non_agent_api.php?' . $query_string;
return file_get_contents($url);
}

You could use file_get_contents:
<?php
file_get_contents($url_with_encoded_params);
Otherwise you are reliant upon the client's browser doing a redirect after receiving the header instruction, you'll also be exposing the end point, and are prone to possible data manipulation.

There are two options:
1. Client side processing
Use ajax call to submit form data to your app server at first then submit same data to third-party API endpoint.
2. Server-side processing
You can simply submit the form to your app server, and then from your app server (after storing data in your database) send a request (may use curl) to third-party API.
I would personally prefer the 2nd one. As it does not exposes the vendor API to the user.

Related

Is it possible to perform a POST API call in PHP with authorization first?

I just started CS at University and wanted to create a little webdev project in my vacation. I created a simple contact form which asks the user for some data (text, dropdown choices). After pressing the submit button I would like to perform a POST api call to the UiPath Orchestrator to trigger a robot...
Since this is the very first time I'm dealing with PHP I'm not quite sure how to approach this problem.
I'm able to grab the data from the submitted form. But now I'm struggling with the API call. I've tested it in Swagger UI and Postman and it works.
Problem:
I have to authenticate via a batcher id which is also retrievable through an API call.
Question:
Does it make sense to create a new function which is responsible for the API call, since I might want to add other forms which trigger other bot processes?
From my research I'm quite sure that I have to use a cURL call (or is this wrong?).. If i need to authenticat every time the submit button is pressed, how can retrieve the token and pass it as a header (or handle idk) argument for the actual POST call?
If you cant understand my problem, I'm very sorry! I will try my best and reformulate it, but since I'm not experienced with this at all I hope you can forgive me.
Already looking forward for your help!
This is my code so far:
add_action('wpcf7_mail_sent','cf7_api_sender');
function cf7_api_sender($contact_form){
$title = $contact_form ->title;
if ($title === 'MA_Demo'){
$submission = WPCF7_Submission::get_instance();
if ($submission){
$posted_data = $submission->get_posted_data();
$firstname = $posted_data['Firstname'];
$lastname = $posted_data['Lastname'];
$department = $posted_data['Departement'][0];
$workload = $posted_data['Workload'][0];
/*
this is what I found so far but ofc it does not work at all.. do I have to put the body (itemData) into the args?
and where can i pull the beacon token and add it?
$url = '"https://cloud.uipath.com/..../..../orchestrator_/odata/Queues/UiPathODataSvc.AddQueueItem"
$args =[
accept: application/json
X-UIPATH-OrganizationUnitId: .....
{ \"itemData\": { \"Name\": \"...\", \"Priority\": \"...\", \"Reference\": \"...\", \"SpecificContent\": {\"key1\": \"Rick \", \"key2\": \"Roll\"} }}
]
*/
/* this was to test if it works to pull data
$myfile = fopen("data.txt", "w") or die("Unable to open file!");
$txt = $firstname.$lastname.$department.$workload;
fwrite($myfile, $txt);
fclose($myfile);
*/
}
}
}
First you'll need to make a call to /api/Account/Authenticate with your tenant, username, and password. It will return something like
{
"result": "HzptFsZpGMS64j5DTb4TqX-cHVv2AtC4noVCQrkHKr54r...",
"targetUrl": null,
"success": true,
"error": null,
"unAuthorizedRequest": false,
"__abp": true
}
Then you use that result in your Add Queue Item call by adding a header item
"Authorization":"Bearer " & result ("Bearer HzptFsZpGMS64...")
This is for Orchestrator on-prem 2019.10 so cloud may be a little different.

Database Post to another Database

I'm currently a front end developer for a website which lets users sign up and then make purchasing of items.For transactions, I'm using an API which the payment gateway company provided but when passing data via AJAX certain sensitive data are exposed for the users to see. I was wondering if there is a way that I can pass my parameters to a database (which I'm going to create), and then let the database do the AJAX posting so sensitive parameters can be hidden from the users. Also the database will store the response from the callback.
The ajax doesn't have to post to a database unless you want it to, but even then the database would not be what posts the data to a remote api. It's up to your backend php to do that.
Using jquery for the ajax call you would use something like:
$.getJSON("your_backend.php", function(result){
//whatever you want to do with the json returned from the remote site.
}
In your_backend.php:
<?php
$user = "user name";
$key = "key"
$headers = array(
'http'=>(
'method'=>'GET',
'header'=>'Content: type=application/json \r\n'.
'user:$user \r\n'.
'key:$key'
)
)
$context = stream_context_create($headers)
$url_returns = file_get_contents($api_url, false, $context);
echo $url_returns
?>
I haven't debugged this, so it won't work until you go through it, but it should give you an idea about how to proceed. Depending on how complex the connection is with the remote api you may need to use the cURL library for php instead of the file_get_contents.
If you want to save the information in your database you would write an insert statement from the backend php.

How to run php function after redirecting user to another page?

I am building a form which the user fills and then I save it into the db. Then I retrieve users who match the criteria and for each one of them I store into another table and also send them an email.
$userModel = new User();
$currentUser = $userModel->findUserById($user->id);
$requestModel = new Requests();
$success = $requestModel->saveRequest($currentUser->usr_id, $tagId, $title, $task, $fixed, $price, $hour, $quality, $multiple, $datetime, $postal, $cityId, $travel);
if($success){
$request = $requestModel->getUserLatestRequest($currentUser->usr_id);
if($request){
$user = new User();
$alluserids= $user->getAllSkillCityUserIds($cityId, $tagId);
$targetId = (array_column($alluserids, 'usr_id'));
//error_log("<pre>targetId".print_r($targetId,true)."</pre>");
foreach($targetId as $target) {
if($target == $currentUser->usr_id){
continue;
}
$lead = new RequestsLead();
$lead->addRequest($request->req_id, $request->req_userid, $target);
$contractor = $userModel->findUserbyId($target);
$nemail = new NotificationsEmail();
$nemail->sendGotRequest($contractor->usr_email, $contractor->usr_firstname);
}
}
$this->flash->success('<div data-toggle="notify" data-onload data-message="Thanks for using our service!." data-options="{"status":"success"}" class="hidden-xs"></div>');
$this->response->redirect($this->url->get(""));
}else{
$this->flash->error('<div data-toggle="notify" data-onload data-message="Sorry! Please try again." data-options="{"status":"danger"}" class="hidden-xs"></div>');
$this->response->redirect($this->url->get("request"));
}
The problem comes when there are alot of users and this function will need to finish running before the user is redirected back to the page with the flash message. How can I modify this so I redirect the user back to the page with the flash message first then run the php foreach functions storing into the db and sending emails after?
I tried switching the order of the functions but once the user is redirected with flash message the php functions stopped proceeding.
PHP is a server side scripting language. It's essentially (but not completely) stateless.
What this means is that when a PHP Page is loaded, it executes it's required PHP code on the server, and then sends the response to the browser. There is no way to re-xecute PHP code after the page has been sent to the client without a new call to the server.
In your case, you're redirceting clients to a new PHP page. That's great, but the new PHP page is a new script being run on the server, it has no concept of what the previous page was doing.
In order to execute the PHP Code AFTER the page has loaded, you will need to use AJAX to send out a request to the PHP Server to execute this request in the background if you want to do it without redirecting the user again, or redirect the user again after displaying the 'flash' message.
Note that with AJAX you can also use the original page - without any redirection - to execute this request AND to display the flash message (at the same time!).
For more information about sharing data between pages:
How do I pass data between pages in PHP?
Passing POST data from one web page to another with PHP
Transfer variables between PHP pages
For more information about AJAX requests and PHP:
Making Ajax service calls with PHP, jQuery, and JSON
(Non-Stackoverflow Link)
Beginner’s Guide to Ajax Development with
PHP (Non-Stackoverflow Link)
What you mention would require some way for the script to keep running beyond the response being sent back to the user. PHP does not work this way - you can start writing content to the output buffer, but the browser will still wait until the entire response has been returned.
Instead, you should think of some process to temporarily store the information you need, and process these asynchronously. e.g. store them to a database and run a cron script or deamon to do this.

How to retain dynamically created input fields values if database fails?

I have a big form around 70 input fields and in the form there are buttons that can create additional input fields. My problem is how do I retain these input fields and their values if something on the server goes wrong upon submitting the form, like database insert failure? I have dynamic validation but what if something goes wrong upon submitting?
You have a lot of options.
You could use ajax to post your form, and then redirect to a new page if successful, or alert the user if not (easiest!)
You could recreate the from on the server side from the post variables (harder with a complex form)
The server could send back the form values on failure, and you can write JS to recreate the form (might be easy if you already have JS to manage the form).
You could pass the actual HTML for the form along with the form values, and have the server use it to recreate the form (you may lose JS events depending on how you hook them up, not the best option in general).
There are many more options that are less useful. I would recommend #1.
For a really simple solution:
You can store the values in an object and only once you've got a confirmed DB insert clear it. If insert fails, and you can retry a few times and it and if fails repeatedly, you can write the values to a CSV log file to handle manually.
More complex solution
Queue. Have all insert requests get queue into a job queue using Zend Jobserver, RabbitMQ or Gearman. Then create a worker process to run the inserts on the other end of the queue. This will allow you to re-run /retry failed jobs.
Why so many fields on a single page? I would reconsider doing this. At any rate, if you have server side validation and it fails you can set up the page to have each field use a default value based on the post value that was sent to the server... So just send them back to the same page and have the input fields value set to the post value.
Here is an example.
$username = array(
'name' => 'username',
'id' => 'username',
'maxlength' => '255',
'size' => '28',
'title' => 'username is required.',
'class' => 'form-text required',
'value' => $this->input->post('username'),
);
<?php echo form_input($username); ?>
here are a couple of function that you can use to store the form values in a session:
//save form inputs
function Hold_Form_Input()
{
$FormPost = array();
foreach ($_POST as $key => $entry)
{
$FormPost[''.$key.'']= $entry;
}
$_SESSION['post_form']= $FormPost;
}
//Clear form values upon success
function Clear_Form_Input()
{
if (isset($_SESSION['post_form']))
{
unset($_SESSION['post_form']);
return true;
}
return false;
}
//Reprint form values as needed
function Keep_on_error($fieldname)
{
if(isset($_SESSION['post_form']) && strlen($_SESSION['post_form'][$fieldname]) > 0)
{
$fill = $_SESSION['post_form'][$fieldname];
return $fill;
}
return false;
}

asp.net form submission problem

I need to accomplish the following and need help with #2 below
My site has a page with form and the submitted form data needs to be written to a database on my site.
After it is written to the database, the same data submitted on the form needs to be sent to a page that processes it on another site so as if the form submission came from a page on that other site. The page that processes it on the other site is a php page.
It's a bit unclear, but my guess is that you're trying to do a 'form post' to the other .php page after your data is written to the database.
You can more information from this wonderful Scott Hanselman article, but here is the summary:
public static string HttpPost(string URI, string Parameters)
{
System.Net.WebRequest req = System.Net.WebRequest.Create(URI);
req.Proxy = new System.Net.WebProxy(ProxyString, true);
//Add these, as we're doing a POST
req.ContentType = "application/x-www-form-urlencoded";
req.Method = "POST";
//We need to count how many bytes we're sending. Post'ed Faked Forms should be name=value&
byte [] bytes = System.Text.Encoding.ASCII.GetBytes(Parameters);
req.ContentLength = bytes.Length;
System.IO.Stream os = req.GetRequestStream ();
os.Write (bytes, 0, bytes.Length); //Push it out there
os.Close ();
System.Net.WebResponse resp = req.GetResponse();
if (resp== null) return null;
System.IO.StreamReader sr = new System.IO.StreamReader(resp.GetResponseStream());
return sr.ReadToEnd().Trim();
}
The ideal solution to your problem is that you create a web service on the php site and your asp.net code calls the web service. http://en.wikipedia.org/wiki/Web_service
Creating a web service in PHP: http://www.xml.com/pub/a/ws/2004/03/24/phpws.html
Calling a web service in ASP.Net: http://www.codeproject.com/KB/webservices/WebServiceConsumer.aspx
Alternatively you could create a http request from your asp.net to the php site posting all the form elements to the php site.
Here is an example: http://www.netomatix.com/httppostdata.aspx
NB: You are almost guaranteed to run into problems with the second approach in the medium to long term, I don't recommend it unless you don't have control over the php site.

Categories