Referer Redirect in a POST call in symfony 4 using URL with annotations comments Routes - refresh

In version symfony 4, I am trying to resolve a redirect in a action done before with a parameter. I Have annotations Routes.
The problem is it is a POST call and I do not know how convert the URL $request->headers->get('referer') in a action_name or how insert the parameters in the call.
$op = 4; //This is an example of a number
$response = new RedirectResponse($request->headers->get('referer'),307,$headers=['op'=>$op]);
return $response;
or
$op = 4; //This is an example of a number
$response = $this->redirect($request->headers->get('referer'));
return $response;
Do you know any way resolves this?

You can inject the router service (instance of RouterInterface) and use its match or matchRequest method.
Ex:
public function testAction(RouterInterface $router, Request $request) {
$route = $router->matchRequest(Request::create($request->headers->get('referer')));
return $this->redirectToRoute($route['_route'], ['op' => 4], 307);
}

Related

Moodle rest post returning error with feature core_user_get_users_by_field

Hi I'm new with moodle and I'm getting an error when calling the webservice.
Currently I'm trying to retrieve a user from moodle with the following function core_user_get_users_by_field and I'm using rest service to do so. I already managed to create a user thus I am authenticated to use the service.
the error that I'm receiving is
Missing required key in single structure: field
The bellow is the code was used to create a User. the issue that I got from the error is that the parameter that I need to send for the post is not formatted well. Does anyone know how to search correctly with this method or any other method.
String token = "token";
String postData = "username=username";
string createRequest = string.Format("http://domain/webservice/rest/server.php?wstoken={0}&wsfunction={1}&moodlewsrestformat=json", token, "core_user_get_users_by_field");
// Call Moodle REST Service
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(createRequest);
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
// Encode the parameters as form data:
byte[] formData =
UTF8Encoding.UTF8.GetBytes(postData);
req.ContentLength = formData.Length;
// Write out the form Data to the request:
using (Stream post = req.GetRequestStream())
{
post.Write(formData, 0, formData.Length);
}
// Get the Response
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
Stream resStream = resp.GetResponseStream();
StreamReader reader = new StreamReader(resStream);
string contents = reader.ReadToEnd();
// Deserialize
JavaScriptSerializer serializer = new JavaScriptSerializer();
if (contents.Contains("exception"))
{
// Error
MoodleException moodleError = serializer.Deserialize<MoodleException>(contents);
}
else
{
// Good
}
The webservice core_user_get_users_by_field needs an associative array given as parameter with the following key:values
'field': 'id'
'values': array of integers (must be an array, possibly with just one value)
In PHP it would be, for example:
$parameters = array('field' => 'id', 'values' => array(13));
It means: the user whose 'id' has the value of 13. Of course, you can use other parameters as well: ('field'=>'lastname', 'values'=> array('Smith'))
The parameters you can choose are the fields of the Moodle 'user' table.
Try to build these parameters in your postData variable.
Here's URL that work with my put this url in postman and set http method to post method
hostname/webservice/rest/server.php?wstoken=any_token&wsfunction=core_user_get_users_by_field&field=email&values[0]=h#fci.com
&moodlewsrestformat=json

Cannot call web api 2 post method with int parameter in URL in Unit Test using Http server

Please ignore the spelling mistake, I cannot copy code so I have typed the whole thing and changed name of controller and method.
WEB API 2
Controller:
// Controller name is Test
public HttpResponseMessage Method1(int param1) // Post method
{
// return string
}
If I create an object of controller in test case then it is working fine. But if I want to test in localhost using following code:
Unit Test:
public void Method1Test()
{
HttpResponseMessage response;
HttpConfiguration config = new HttpConfiguration();
config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{id}");
HttpServer server = new HttpServer(config);
using(var client = new HttpClient(server))
{
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "http://localhost:5022/api/test?param1=1");
request.Content = new ObjectContent<int>(param1, new JsonMediaTypeFormatter());
response = client.SendAsync(request, CancellationToken.None).Result;
};
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
}
Now, my test case is failing. I used the same code in different project and it worked. May be it is the way I am trying to call Post method. Is this the right way to call post method with Int parameter in URL?
In help page, under API column it shows:
POST api/test/param1={param1}
Also I have put some stop point in actual service I am cursor is not stopping at that point. Why?
If I want to call the same service from browser, what URL should I pass? Is it -
http://localhost:5022/api/test?param1=1
Or something else?
I figured it out. Following is the correct unit test method but this has some extra information which I have not provided earlier i.e., passing object as an input for the service.
private void Method1Test(ObjectClass obj)
{
HttpResponseMessage response = null;
HttpConfiguration config = new HttpConfiguration();
config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{id}");
HttpServer server = new HttpServer(config);
using (var client = new HttpClient(server))
{
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "http://localhost:5022/api/test/1");
request.Content = new ObjectContent<ObjectClass>(obj, new JsonMediaTypeFormatter());
response = client.SendAsync(request, CancellationToken.None).Result;
};
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
}
So the correct URL that I was looking for was
http://localhost:5022/api/test/1
Sorry, It took long to post this answer. This method is working like a charm for more then 2 years.

post data - ngResource AngularJS

Hello !
I develop a RESTful webapp with AngularJS, I use the ngResource module to send http requests. The webservice is developped with FuelPHP.
I'm having a problem to creating a resource with the $save method of ngResource. My web service doesn't receive post data.
When I check the http request with Firebug, I can see the post data.
I don't understand why the post data are not received by the webservice. So if you have an idea, it would be cool to help me.
Sorry for my bad level in English.
Here is the code :
Service :
app.factory('Medication', ['$resource', 'global', function ($resource, global) {
return $resource(global.API+'/medication/medication', {}, {})
}])
Method in the controller :
$scope.addMedication = function() {
var newMed = new Medication();
newMed.name = 'nameValue';
newMed.increaseinr = 1;
newMed.details = 'detailsValue';
newMed.$save();
}
I believe this is an issue with how PHP is handling the POST. When using AngularJS $resource it will POST the object with JSON as the post's BODY. PHP does not see this as a regular parameter. I've had to do this in other PHP (never used Fuel)
$requestBody = file_get_contents('php://input');
$requestBody = json_decode($requestBody, true);
Then you should be able to inspect $requestBody as a normal json object.
You need to config the $save method with a request method of 'POST'
you can set the default option 'transformRequest' of $http to change the transfer formation of the post data.
var myApp = angular.module('myApp');
myApp.config(function ($httpProvider) {
$httpProvider.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";
$httpProvider.defaults.transformRequest = function(data){
if (data === undefined) {
return data;
}
return $.param(data);
}
});
Thanks for your answers.
Indeed, data is post in the request's body.
With FuelPHP, I used Input::json('key') to get the values (and not Input:post('key'))

having trouble sending facebook notification via ajax call to php

In my javascript I have a click event that triggers an ajax call to the php page where I send my notification from. I chose to do it this way because the documentation advises against using your app secret in any client side code, and the notifications parameters requires an access token that you can only get using the app secret.
The problem I'm having is that even though I'm logged in, $facebook->getUser() is returning 0 in php, so the api call I make afterwards to send the notification wont work. My user is already logged in via the client side code, so how do I get the message to the php that they're logged in so the notification can be sent.
//JS
$.ajax({
url : "http://xxxxxo/bn/notification.php",
type : 'POST',
data: {notify: notify },
success : function (result) {
console.log(result);
},
error : function () {
alert("error sending notification");
}
});//closes ajax
//PHP
<?php
require_once(dirname(__FILE__).'/php-sdk/facebook.php') ;
$APPLICATION_ID = '1402xxxxx7';
$APPLICATION_SECRET = 'ce71d6bbxxxxx5f55a';
$fb_app_url = "http://apps.facebook.com/myAPP";
$config = array();
$config['appId'] = $APP_ID;
$config['secret'] = $APP_SECRET;
$config['cookie'] = true;
$facebook = new Facebook($config) or die('Error is here!');
$facebook = new Facebook(array(
'appId' => $APP_ID,
'secret' => $APP_SECRET,
'fileUpload' => true
));
$notify = $_REQUEST['notify'];
$userid = $facebook->getUser();
/*IF WE HAVE A LOGGED IN USER AND THE 'NOTIFY' REQUEST VALUE, THEN SEND THE NOTIFICATION.
BUT MY USER ID IS 0. HOW DO I GET PHP TO RECOGNIZE ME AS LOGGED IN WITHOUT HAVING TO FORCE MY USER TO LOG IN VIA PHP AFTER THEY'VE ALREADY LOGGED IN CLIENT SIDE?*/
if($userid && $notify){
$token_url ="https://graph.facebook.com/oauth/access_token?" .
"client_id=" . $APP_ID .
"&client_secret=" . $APP_SECRET .
"&grant_type=client_credentials";
$app_token = file_get_contents($token_url);
$app_token = str_replace("access_token=", "", $app_token);
$data = array(
'href'=> 'https://apps.facebook.com/thebringernetwork/',
'access_token'=> $app_token,
'template'=> 'test'
);
$sendnotification = $facebook->api('/1622649653/notifications', 'post', $data);
}else{
//handle error
}
?>
The first thing I noticed is that you define your app id as $APPLICATION_ID but use it as $APP_ID (and the same goes for your app secret). But since you didn't mention any errors and $facebook->getUser(); executes I'm guessing this is just a bad copy-paste.
Now for the sake of answering this question I'm going to presume that you are using the latest versions of both JS and PHP SDKs. These use oauth 2.0 and change the way you pass the login information from JS to PHP.
According to Facebook Developer Blog removing $config['cookie'] = true; and setting oauth to true in your JS configuration should work. Just make sure to refresh the site after the login.
The solution I've found in my own project is to disable cookies altogether and simply pass the access token to my PHP script.
In your JS call your PHP script like this (make sure to call this after the JS login!):
$.ajax({
url : "http://xxxxxo/bn/notification.php",
type : 'POST',
data: {
notify: notify,
token: FB.getAuthResponse()['accessToken'] // add your access token
},
success : function (result) {
console.log(result);
},
error : function () {
alert("error sending notification");
}
});
And in your PHP script add this after creating the FB object.
$facebook->setAccessToken($_POST['token']); // set the users access token
Doing things this way will also get rid of any need to refresh the website after the login.
Yes, this is a common problem when using the PHP SDK in combination with AJAX:
When you make an AJAX request, the PHP SDK deletes the cookies where the authorization information are stored, and then the next call to getUser will just return 0, because this method tries to find the current user id in those cookies – apparently there is something in the OAuth 2.0 spec that demands this behavior to prevent some sort of click-jacking attack.
But the info will still be stored in the session, so you can read the user id (and the user access token, should you need it) from there:
$user_id = $_SESSION['fb_YourAppIdHere_user_id'];
$user_access_token = $_SESSION['fb_YourAppIdHere_access_token'];
Replace YourAppIdHere with your app id (so it becomes fb_1234567890_user_id resp. fb_1234567890_access_token) to get the correct names of those session keys.

Read and Write Cookie in Symfony2

I want to store some information in the local browser cookie. After hours looking for a nice tutorial, I managed to store some data in a non-session cookie:
controller - indexAction()
$cookieGuest = array(
'name' => 'mycookie',
'value' => 'testval',
'path' => $this->generateUrl('my_route'),
'time' => time() + 3600 * 24 * 7
);
$cookie = new Cookie($cookieGuest['name'], $cookieGuest['value'], $cookieGuest['time'], $cookieGuest['path']);
$response = new Response();
$response->headers->setCookie($cookie);
$response->send();
I wonder if this is the correct way. Furthermore I tried several ways to read the cookie with the HttpFoundation Component, but without success. Is there another way than accessing the cookie via $_COOKIE['mycookie'] ?
Here is where I try to read the cookie
controller - cookieAction()
public function cookieAction($_locale, $branch, $page)
{
$response = new Response();
$cookies = $response->headers->getCookies();
var_dump($cookies);
// TODO: Get params for indexAction from cookie if available
return $this->indexAction($_locale, $branch, $page);
}
This is the correct way of setting cookie.
To read cookie already written in the browser do:
$request->cookies->get('myCookie');
But after I created cookie in the $response object:
$cookie = new Cookie('myCookie', 'contentOfMyCookie');
$response = new Response();
$response->headers->setCookie($cookie);
I call this method:
$response->headers->getCookies();
I get an array of cookies, which are to be written in the browser - not those already existing there.
Figuratively, between $request and $response there is a time of executing controller's code.
Besides, in a twig template you can use
{{ app.request.cookies.get('myCookie') }}
you thus get value of the cookie already written in the browser, not that from the $response object! Newly created cookie from the browser you can read only after having reloaded page (ajax doesn't need to reload whole page).
To sum it up, you can read cookies using $request object, and create them with $response object. (Obviously, for some reasons, you can also read $response object cookies - but these are rather rare situations).
$response->headers->getCookies();
should return an array of cookies look in ResponseHeaderBag class for more information about that function
this can be useful for someone trying to make cookies in symfony2 :
use Symfony\Component\HttpFoundation\Cookie;
Example how to use Cookies and Session:
<?php
namespace AppBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\Response;
class DefaultController extends Controller
{
public function indexAction()
{
// Set session value
$session = $this->getRequest()->getSession();
$session->set('test', 1);
// Get session value
$value = $session->get('test');
// Set cookie value
$response = new Response();
$cookie = new Cookie('test', 1, time()+3600);
$response->headers->setCookie($cookie);
// Get cookie value
$this->getRequest()->cookies->get('test');
}
}
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\Response;
// set current active tab in cookie
$cookie = new Cookie('myProfileActiveTab', 'myaddress', strtotime('now + 60 minutes'));
$response = new Response();
$response->headers->setCookie($cookie);
$response->send();
// get current active tab from cookies
$cookies = $request->cookies;
if ($cookies->has('myProfileActiveTab')) {
$activetab = $cookies->get('myProfileActiveTab');
}
More interesting cookies information links (http_fundation component for symfony2):
Symfony2 http_fundation component
Symfony2 http_fundation api
Symfony2 http_fundation component (spanish)