React-App Axios POST to php.file with sentMail ->works from localhost but empty $_Post['***'] from Server - reactjs

I have an mail.php file in root on my hosting space.
Do I call mail.php with axios from my localhost from within the development server (npm start) it works fine.
The form who triggers the POST sends the data to my Email address.
After the build process and the upload on my web space, I still receive an email but there the input is missing.
Axios POST:
const formData = new FormData();
// formData.append('name', datas.name);
// formData.append('email', datas.email);
// formData.append('message', datas.message);
// formData.append('nice', nice)
formData.append('name', 'Klara');
formData.append('email', 'klara#gmail.com');
formData.append('message', 'Hallo');
//POST data to the php file
try{
axios.post('https://salevsky.net/mail.php', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
});
} catch(error) {
PHP file:
<?php
header('Access-Control-Allow-Origin: *');
header('Content-Type: multipart/form-data');
$to = "blablub#webyy.net";
$subject = "Contact Us";
// // Email Template
$message .= "<b>Message : </b>".$_POST['name']."<br>";
$message .= "<b>Email Address : </b>".$_POST['email']."<br>";
$message .= "<b>Message : </b>".$_POST['message']."<br>";
$header = "From:".$_POST['email']." \r\n";
$header .= "MIME-Version: 1.0\r\n";
$header .= "Content-type: text/html\r\n";
$retval = mail ($to,$subject,$message,$header);
// // message Notification
if( $retval == true ) {
echo json_encode(array(
'success'=> true,
'message' => 'Message sent successfully'
));
}else {
echo json_encode(array(
'error'=> true,
'message' => 'Error sending message'
));
}
?>
I tried various DataTypes and ContentForms.
At least headers: { "Content-Type": "multipart/x-www-form-urlencoded" },
I wonder why content type in request header is not changing. I see this in the Browser under Network. It's application/json all time. But I don't know if it's an important fact.

Related

Sending JSON HTTP request using Guzzle HTTP: Result parameters are not as expected

I want to send a JSON request to an endpoint but the results that I get don't match the parameters requested.
This is the array
$datas = [
"institutionCode" => $institutionCode,
"brivaNo" => $brivaNo,
"custCode" => $custCode
];
This is the response using Guzzle HTTP
try {
$response = $client->request($verb, $endpoint,
[
"headers" =>
[
"Authorization" => "Bearer " . $token,
"BRI-Timestamp" => $timestamp,
"BRI-Signature" => $signature,
],
"json" => $datas
]
);
return $response;
}
catch (\GuzzleHttp\Exception\RequestException $e) {
return $e->getResponse();
}
This is the response from the endpoint
{
"status": false,
"errDesc": "Institution Code Tidak Boleh Kosong",
"responseCode": "03",
"data": {
"{\"institutionCode\":\"J104408\",\"brivaNo\":\"77777\",\"custCode\":\"7878787878\"}": ""
}
}
Why does the "data" not match the data array I have given above and instead creates a new pattern with a backslash in it?
This is the native way using cURL PHP
if there is someone can turn it into a Guzzle Http, it will help me,
after I tried this code, it also didn't help at all
$institutionCode = "J104408";
$brivaNo = "77777";
$custCode = "123456789115";
$payload = "institutionCode=".$institutionCode."&brivaNo=".$brivaNo."&custCode=".$custCode;
$path = "/v1/briva";
$verb = "DELETE";
$base64sign = generateSignature($path,$verb,$token,$timestamp,$payload,$secret);
$request_headers = array(
"Authorization:Bearer " . $token,
"BRI-Timestamp:" . $timestamp,
"BRI-Signature:" . $base64sign,
);
$urlPost ="https://sandbox.partner.api.bri.co.id/v1/briva";
$chPost = curl_init();
curl_setopt($chPost, CURLOPT_URL,$urlPost);
curl_setopt($chPost, CURLOPT_HTTPHEADER, $request_headers);
curl_setopt($chPost, CURLOPT_POSTFIELDS, $payload);
curl_setopt($chPost, CURLINFO_HEADER_OUT, true);
curl_setopt($chPost, CURLOPT_RETURNTRANSFER, true);
$resultPost = curl_exec($chPost);
$httpCodePost = curl_getinfo($chPost, CURLINFO_HTTP_CODE);
curl_close($chPost);
$jsonPost = json_decode($resultPost, true);
return $jsonPost;

no 'Access-Control-Allow-Origin' Symfony 3 and React

I am experiencing a major concern. I develop an api with symfony 3. This api is queried on Front side with React. The server used back side (API) is http://127.0.0.1:8000. And the server used on the Front side is http://localhost:3000.
When I call the api from the front, I have two errors:
- 405 Method Not Allowed
- Access to XMLHttpRequest at 'http://127.0.0.1:8000/users/email/settings' from origin 'http://localhost:3000' has been blocked by: CORS policy: Response to preflight check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
However, I specified the correct method (patch) and configured the header from the API:
Here is the detailed code:
API (back with symfony)
/**
* #Route("/users/email/settings", methods={"PATCH"})
* #param Request $request
* #param FlashMessage $flashMessage
*/
public function usersEmailEditAction(Request $request, FlashMessage $flashMessage)
{
if($request->getContent())
{
$data = json_decode($request->getContent(), true);
$em = $this->getDoctrine()->getManager();
$user = $this->get('security.token_storage')->getToken()->getUser();
$editUser = $em->getRepository(User::class)->find($user->getId());
if (!$editUser) {
return $flashMessage->messageError("USER_NOT_FOUND", 1);
}
if (!$data['password']) {
return $flashMessage->messageError("PASSWORD_NOT_FOUND", 1);
}
if (!filter_var($data['email'], FILTER_VALIDATE_EMAIL)) {
return $flashMessage->messageError("INVALID_EMAIL", 1, "format email invalid");
}
if (!filter_var($data['confirmEmail'], FILTER_VALIDATE_EMAIL)) {
return $flashMessage->messageError("INVALID_EMAIL", 1, "format email invalid");
}
if ($data['email'] != $data['confirmEmail']) {
return $flashMessage->messageError("NO_MATCHING_EMAIL", 1, "les emails sont différents");
}
// on vérifie le mot de passe
$encoder = $this->get('security.password_encoder');
$isPasswordValid = $encoder->isPasswordValid($user, $data['password']);
// Le mot de passe n'est pas correct
if (!$isPasswordValid) {
return $flashMessage->messageError("INCORRECT_PASSWORD", 1);
}
$editUser->setEmail($data['email']);
$editUser->setUpdatedAt(new \DateTime());
$em->flush();
return $flashMessage->messageSuccess("EMAIL_UPDATED_SUCCESSFULLY", 0);
}else {
return $flashMessage->messageWarning("NOTHING_UPDATED", 2);
}
}
the return $flashMessage
public function messageSuccessAction($message, $code, $desc = null)
{
$response = new Response();
$response->setContent(json_encode([
'error' => $code,
'message' => $message
]));
$response->headers->set('Content-Type', 'application/json');
$response->headers->set('Access-Control-Allow-Origin', 'http://localhost:3000');
$response->headers->set('Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, PATCH, OPTIONS');
return $response;
//return new JsonResponse(array("error" => $code, "message" => $message));
}
public function messageErrorAction($message, $code, $desc = null)
{
$response = new Response();
$response->setContent(json_encode([
'error' => $code,
'message' => $message
]));
$response->headers->set('Content-Type', 'application/json');
$response->headers->set('Access-Control-Allow-Origin', 'http://localhost:3000');
$response->headers->set('Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, PATCH, OPTIONS');
return $response;
//return new JsonResponse(array("error" => $code, "message" => $message));
}
public function messageWarningAction($message, $code, $desc = null)
{
$response = new Response();
$response->setContent(json_encode([
'error' => $code,
'message' => $message
]));
$response->headers->set('Content-Type', 'application/json');
$response->headers->set('Access-Control-Allow-Origin', 'http://localhost:3000');
$response->headers->set('Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, PATCH, OPTIONS');
return $response;
//return new JsonResponse(array("error" => $code, "message" => $message));
}
Request API from Front (use Axios)
requestAPI = (myPassword, newEmail, confirmEmail) => {
axios.patch('http://127.0.0.1:8000/users/email/settings', {
crossdomain: true,
password: myPassword,
email: newEmail,
confirmEmail: confirmEmail
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
}
I also tried without crossdomain, but nothing.
Do you have any idea ? Thank you for your helps
Is the call that gets the 405 Method Not Allowed by any chance an OPTIONS call? Also called a "preflight request".
For all your CORS needs you should include the NelmioCorsBundle, it is easily configurable and you don't need to set your own CORS headers.
What happens here is, your browser will check first whether the server understands the CORS protocol with an OPTIONS call. But that isn't answered by your application, at least not with the correct CORS headers, so your PATCH call is never issued by your browser because of that. The error message even says so. "Response to preflight check: No 'Access-Control-Allow-Origin' header is present on the requested resource."

AJAX post request to third party REST api

. I am using laravel backend as API and angular as frontend which calls laravel api. Laravel api access the teamwork api through basic authentication using curl.
Now I am working with teamwork Api. Trying to create a comment using the API.
API documentation describes following.
{
"comment": {
"body": "Reply to earlier comment",
"notify": "",
"isprivate": false,
"pendingFileAttachments": "",
"content-type": "TEXT"
}
}
//ref : http://developer.teamwork.com/comments#creating_a_commen
in my ajax call i have used following
var data = $.param({
'body' : commentBodyValue, //variable
'notify': "",
'isPrivate':false,
"pendingFileAttachments": "",
"content-type": "TEXT"
});
My post does not give error, but it also do not create a new comment too. What am I missing? I think i failed to arrange data according to the format allowed in api. Can you kindly help me to fix it?
Edit:
Angular Controller:
//add new comment
$scope.addComment = function(taskId,commentAuthorId)
{
var commentBod = document.getElementById("commentBody");
var commentBodyValue = commentBod.value;
console.log("new comment : "+ taskId + commentBodyValue);
//submit the post request
//$http.post();
//using jquery function param to serialize
var data = $.param({
'body' : commentBodyValue,
'notify': "",
'isPrivate':false,
"pendingFileAttachments": "",
"content-type": "TEXT"
});
var config = {
headers : {
// 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8;',
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
}
var url = "http://abounde.com/portal/api/post_comment/"+taskId;
$http.post(url,data,config)
.then(
function(response){
//success
console.log("response : Submitted :D " + response);
},
function(response){
//failure
console.log(response);
}
);
}
Edit 2
Laravel route and controller
Routes:
//post comment to resource
Route::post('post_comment/{task_id}',[
'uses'=>'PortalController#postComment',
'as'=>'portal.client.postComment'
]);
Controller:
//post comment at task
public function postComment(Request $request, $task_id)
{
$secretApiKey = $request->session()->get('secretApiKey');
if(!empty($secretApiKey)){
//post the msg
$this->callTeamworkApi($secretApiKey,"tasks/".$task_id."/comments.json");
}else{
return response()->json(['response'=>"Not Logged In"]);
}
}
//authentication method
public function callTeamworkApi($secretApiKey, $apiCallString)
{
//cURL
$password = "xxx";
$channel = curl_init();
//options
curl_setopt($channel, CURLOPT_URL, "http://projects.abounde.com/".$apiCallString); // projects.json?status=LATE gets all late projects
curl_setopt($channel, CURLOPT_HTTPHEADER,
array(
"Authorization: Basic " . base64_encode($secretApiKey . ":" . $password)
));
$msg = curl_exec($channel);
curl_close($channel);
return response()->json(['res'=>$msg]);
}
EDIT 3: Contacted with teamwork Api support.
After their advice i came up with following code
//post comment at task
public function postComment(Request $request, $task_id)
{
$secretApiKey = $request->session()->get('secretApiKey');
if(!empty($secretApiKey)){
//post the msg
$comment=array();
// $comment['body']=$request->input('body');
// $comment['notify']=$request->input('notify');
// $comment['isprivate']=$request->input('isprivate');
// $comment['pendingFileAttachments']=$request->input('pendingFileAttachments');
// $comment['content-type']=$request->input('content-type');
$comment['comment']['body']="test";
$comment['comment']['notify']="";
$comment['comment']['isprivate']=false;
$comment['comment']['pendingFileAttachments']="";
$comment['comment']['content-type']="text";
$this->callTeamworkPostApi($secretApiKey,"tasks/".$task_id."/comments.json",json_encode($comment));
//var_dump($comment);
//return response()->json(['response'=>"Trying"]);
}else{
return response()->json(['response'=>"Not Logged In"]);
}
}
}
///
public function callTeamworkPostApi($secretApiKey, $apiCallString,$comment)
{
//cURL
$password = "xxx";
$channel = curl_init();
//options
curl_setopt($channel, CURLOPT_URL, "http://projects.abounde.com/".$apiCallString); // projects.json?status=LATE gets all late projects
curl_setopt($channel, CURLOPT_HTTPHEADER,
array(
"Authorization: Basic " . base64_encode($secretApiKey . ":" . $password)
));
curl_setopt($channel, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($channel, CURLOPT_POSTFIELDS, $comment);
$msg = curl_exec($channel);
curl_close($channel);
var_dump($msg);
//return response()->json(['res'=>$msg]);
}
var_dump($comment) gives
string(107) "{"comment":{"body":"test","notify":"","isprivate":false,"pendingFileAttachments":"","content-type":"text"}}"
However the api still do not save the comment. It has to be a curl post method issue. Right?
Edit 4:
I have done a var_dump(curl_getinfo($channel));
this gave me following response.
array(26) { ["url"]=> string(55) "http://projects.abounde.com/tasks/8199861/comments.json" ["content_type"]=> NULL ["http_code"]=> int(500) ["header_size"]=> int(229) ["request_size"]=> int(311) ["filetime"]=> int(-1) ["ssl_verify_result"]=> int(0) ["redirect_count"]=> int(0) ["total_time"]=> float(0.5) ["namelookup_time"]=> float(0) ["connect_time"]=> float(0.109) ["pretransfer_time"]=> float(0.109) ["size_upload"]=> float(107) ["size_download"]=> float(0) ["speed_download"]=> float(0) ["speed_upload"]=> float(214) ["download_content_length"]=> float(0) ["upload_content_length"]=> float(107) ["starttransfer_time"]=> float(0.5) ["redirect_time"]=> float(0) ["redirect_url"]=> string(0) "" ["primary_ip"]=> string(13) "23.23.184.208" ["certinfo"]=> array(0) { } ["primary_port"]=> int(80) ["local_ip"]=> string(11) "192.168.0.6" ["local_port"]=> int(31657) }
The response code 500 may points to the fact that teamwork has some kind of internal issues.
The issue i found out is that you are not passing your comment data which you received from the frontend to the curl the request in callTeamworkApi().Try below code and see if you get your desired output or not
//post comment at task
public function postComment(Request $request, $task_id)
{
$secretApiKey = $request->session()->get('secretApiKey');
if(!empty($secretApiKey)){
//post the msg
$comment=array();
$comment['body']=$request->input('body');
$comment['notify']=$request->input('notify');
$comment['isPrivate']=$request->input('isprivate');
$comment['pendingFileAttachments']=$request->input('pendingFileAttachments');
$comment['content-type']=$request->input('content-type');
$this->callTeamworkApi($secretApiKey,"tasks/".$task_id."/comments.json",json_encode($comment));
}else{
return response()->json(['response'=>"Not Logged In"]);
}
}
//authentication method
public function callTeamworkApi($secretApiKey, $apiCallString,$comment)
{
//cURL
$password = "xxx";
$channel = curl_init();
//options
curl_setopt($channel, CURLOPT_URL, "http://projects.abounde.com/".$apiCallString); // projects.json?status=LATE gets all late projects
curl_setopt($channel, CURLOPT_HTTPHEADER,
array(
"Authorization: Basic " . base64_encode($secretApiKey . ":" . $password)
));
curl_setopt($channel, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($channel, CURLOPT_POSTFIELDS, $comment);
$msg = curl_exec($channel);
curl_close($channel);
return response()->json(['res'=>$msg]);
}
Solution Found:
While calling to the teamwork API, it is essential that the content-type is set to Json. and the information should be in header file. header variable should be a multi array which takes authentication and content type information.
$headers = array();
$headers[] = "Authorization: Basic " . base64_encode($secretApiKey . ":" . $password);
$headers[] = "Content-Type: application/json";
//pass it as variable
curl_setopt($channel, CURLOPT_HTTPHEADER, $headers);
And then it works like charm.
returns following after creation of the comment.
{"commentId":"4294639","STATUS":"OK"}

how to send emails with PHPmailer from WordPress Rest API end point

function my_send_email($name,$email, $current_user, $status, $subject, $Message) {
//most of the code here is from https://github.com/PHPMailer/PHPMailer/tree/master/examples
require_once ABSPATH . WPINC . '/class-phpmailer.php';
require_once ABSPATH . WPINC . '/class-smtp.php';
// build message body`enter code here`
$body = '
<html>
<body>
<h1>My Email</h1>
</body>
</html>
';
try {
//Create a new PHPMailer instance
$mail = new PHPMailer;
//Tell PHPMailer to use SMTP
$mail->isSMTP();
//Enable SMTP debugging
$mail->SMTPDebug = 2;
//Ask for HTML-friendly debug output
$mail->Debugoutput = 'html';
//Set the hostname of the mail server
$mail->Host = "mail.example.com";
//Set the SMTP port number - likely to be 25, 465 or 587
$mail->Port = 25;
//Whether to use SMTP authentication
$mail->SMTPAuth = true;
//Username to use for SMTP authentication
$mail->Username = "contact#example.com";
//Password to use for SMTP authentication
$mail->Password = "1234";
//Set who the message is to be sent from
$mail->setFrom('contact#example.com', 'sender_name');
//Set an alternative reply-to address
$mail->addReplyTo('alternative_contact#example.com', 'alternative_contact_name');
//Set who the message is to be sent to
$mail->addAddress($email, $name);
//Set the subject line
$mail->Subject = 'PHPMailer SMTP test';
//Read an HTML message body from an external file, convert referenced images to embedded,
//convert HTML into a basic plain-text alternative body
//$mail->msgHTML(file_get_contents(dirname(__FILE__) .'/contents.html'));
$mail->MsgHTML($body);
//Replace the plain text body with one created manually
$mail->AltBody = 'This is a plain-text message body';
$success=$mail->send();
//send the message, check for errors
if ($success) {
return array('mailError' => false, 'message' => 'email sent! ' . $mail->ErrorInfo , 'body'=>$body);
} else {
return array('mailError' => true, 'message' => 'email error! ' . $mail->ErrorInfo , 'body'=>$body);
}
} catch (phpmailerException $e) {
return array('mailError' => false, 'message' => 'email error! ' . $e->errorMessage() , 'body'=>$body); //Pretty error messages from PHPMailer
} catch (Exception $e) {
return array('mailError' => false, 'message' => 'email error! ' . $e->getMessage() , 'body'=>$body); //Boring error messages from anything else!
}
}
function my_register_endpoints(){
register_rest_route(
'my_namespace/v1',
'/abc/',
array(
'methods' => 'POST',
'callback' => 'my_end_point',
'args' => array(
.....
),
'permission_callback' => function (WP_REST_Request $request) {
if(!is_user_logged_in()){
.....
}
return true;
}
)
);
}
add_action('rest_api_init','my_register_endpoints');
//endpoint
function my_end_point(WP_REST_Request $request){
global $current_user;
$sender = wp_get_current_user();
$shortMsg=$request['shortMessage'];
$subject="Some text";
$email_resualt=my_send_email("reciver_name","reciver_email",$sender,$status,$subject,$shortMsg);
if($email_resualt['mailError']==false){
process.. $itemes, $item ..
$message='email sent!';
return array('message' => $message,'items' => $items, 'item'=>$item);
} else {
return new WP_Error('email error',__('some message','email-error'),$request['id']);
}
}
I am using angularJS $http.post to call the API end point, The emails are sent and I can see them on my inbox, but for some reason I am getting back undefined response:
Related errors on Chrome console:
1) SyntaxError: Unexpected token S in JSON at position 0
2) TypeError: Cannot read property 'message' of undefined
I use response.message in my client side code but as I stated above but as the response is empty I am getting errors.
I have other end points in my WordPress PHP code that looks the same but doesn't include send emails with PHPmailer and works fine. and even this end point without the send email functionality was also working fine.
I tried to debug it for two days but still I am not sure where the issue in my code?
I found what the issue was, In my send email function I had the lines:
//Enable SMTP debugging
$mail->SMTPDebug = 2;
$mail->Debugoutput = 'html';
And appears that because debugging was turned on the response from my end point was to match for angular to handle after I commented these two lines the response was well structured for for angular to be able to parse it.
The hint to solve it was in the following post Syntax error: Unexpected number at Object.parse, PHP to AngularJS

Upload image from ng-camera with ng-file-upload to intervention

I'm using danialfarid/ng-file-upload and bcabanes/ng-camera. This is my code (coffee):
file = $scope.vm.picture
if (file)
Upload.upload({
url: "::imagenes/store",
fields: {'Title': "test"},
file: file,
headers: {
'Accept': 'application/json;odata=verbose', 'content-type': 'image/jpeg', 'X-RequestDigest': $("#__REQUESTDIGEST").val()
}
}).success((data, status, headers)->
console.log('Complete!');
);
My navigator shows (slowly) that data were sent, but I don't know how to save that image with Laravel Intervention. Here's some code:
$file = Request::file("file");
$info = explode(".", $file->getClientOriginalName());
I don't know if I can use Request::file("file"), because it's a base64 image taken by ng-camara:
ng-camera(
capture-message="Sonrie!"
output-height="320"
output-width="426"
crop-height="320"
crop-width="426"
image-format="jpeg"
jpeg-quality="100"
action-message="Tomar foto"
snapshot="vm.picture"
flash-fallback-url="/images/webcam.swf"
shutter-url="/sounds/shutter.mp3"
style="display: inline-block")
How do I send the base64 image and how do I save it? Thank you for your help!
Well, I got it like this:
(Coffee)
$scope.upload = ()->
file = $scope.vm.picture
if (file)
file = file.replace(/^data\:image\/\w+\;base64\,/, '')
$http.post('imagenes/store', {foto: file, paciente_id: $scope.paciente.id}).then( (r)->
toastr.success 'Uploaded correctly.'
, (r2)->
toastr.error 'Uploaded error', 'Error'
)
I call the function with a button (jade):
md-button.md-raised(ng-show="vm.picture" type="button" ng-click="upload()") Save
In Laravel:
public function postStore()
{
$folder = 'images/perfil/';
if (Request::has('foto')) {
$folder = 'images/perfil/';
File::makeDirectory($folder, $mode = 0777, true, true);
// THIS IS THE IMPORTANT!!! ------------
$file = Request::input("foto");
$binary_data = base64_decode( $file );
$result = file_put_contents($folder .'/aName.jpg', $binary_data);
// -------------------------------------
$img = Image::make($folder . '/aName.jpg');
$img->fit(300);
$img->save();
}
return 'Saved';
}

Resources