MethodNotAllowedHttpException in compiled.php line 8518 - laravel-5

Im sending request from salesforce to laravel then laravel return the result and display them on visual force page
Error Detail
Apex Method
public List<SelectOption> getItems()
{
HttpRequest req = new HttpRequest();
HttpResponse res = new HttpResponse();
Http http = new Http();
req.setEndpoint('http://clozer.3spire.net/public/goclozer/country');
req.setMethod('GET');
req.setCompressed(false);
req.setBody('key1=value1&key2=value2');
req.setHeader('Content-Type', 'application/json');
try {
res = http.send(req);
} catch(System.CalloutException e) {
system.debug('Callout error: '+ e);
}
getAllCountry = (Map<String, String>)JSON.deserialize(res.getBody(),Map<String, String>.class);
List<SelectOption> option = new List<SelectOption>();
option.add(new SelectOption('0','--None--'));
for(String c : getAllCountry.values())
{
option.add(new SelectOption(c,c));
}
return option;
}
Expected Result
{"0":"Aruba","1":"Antigua and Barbuda","2":"United Arab Emirates","3":"Afghanistan","4":"Algeria","5":"Azerbaijan","6":"Albania","7":"Armenia","8":"Andorra","9":"Angola","10":"American Samoa","11":"Argentina","12":"Australia","13":"Ashmore and Cartier Islands"}
Laravel 5 Route
Route::get('/goclozer/country','GoClozerController#getCountry');
Laravel 5 Method
public function getCountry()
{
$country = \App\Country::all();
$names = array();
foreach($country as $c)
{
$names[] = $c->name;
}
echo json_encode($names,JSON_FORCE_OBJECT);
}
How can i get ride of this error
Thanks in advance

MethodNotAllowedHttpException means that you're using wrong HTTP verb ( Get, Post, Put, Delete ...). You've route defined for GET, but you may be posting data
The modification (as I assume you just want to retrieve the country names only) can be achieved by
$countries = Country::all(['name']);
this will only retrieve the names of the countries from the table, you can add more fields if you want to.
Controller gets a request, returns a response. You're not returning any response. just echoing the result. You can do the following,
return $countries;
This will simply return the JSON with country names.
You don't have to put an explicit slash at the front of route declaration. you can even write like the following and that will work too.
Route::get('goclozer/country','GoClozerController#getCountry');

Related

gettin request/query parameters with less code

Is this:
$paginate = $request->get('paginate');
Equivalent to this, for getting a query param if it is present or assign to the associated variable "null" it it is not present:
if ($request->has('paginate')) {
$paginate = $request->get('paginate');
} else {
$paginate=null;
}
According to get() method documentation:
This method belongs to Symfony HttpFoundation and is not usually needed when using Laravel.
Alternatively you can use filled and $request->paginate
So it checks if the request has the "item"and it has value.
$paginate = null;
if ($request->filled('paginate')){
$paginate = $request->paginate;
}

How to forward from POST to GET handler

I need to forward from a POST to a GET request.
Somehow I end up in an endless loop. It always goes to the POST handler. Of course GET and POST have the same URL . But that's normal in REST design.
So how can I forward to the GET handler. Also in the error case I need to have redirectAttributs to have the error attributes available in the GET method .
That is my code.
#RequestMapping(value = "/user/holiday", method = RequestMethod.GET)
public String holiday(Model model) {
model.addAttribute("holiday", new Holiday());
model.addAttribute("edit", false);
List<Holiday> lstHoliday = holidayDao.findByUser(userDao.findByUserName(Util.getLoggedInUserName()));
model.addAttribute("Util", new Util());
model.addAttribute("holidaylist", lstHoliday);
model.addAttribute("residualLeave",Util.calculateResidualHoliday(lstHoliday));
return "/user/holiday";
}
#PostMapping(value = "/user/holiday")
public String holidayPost(Model model, Holiday holiday,RedirectAttributes redirectAttrs) throws ParseException {
DateTimeFormatter df = DateTimeFormatter .ofPattern("dd-MM-yyyy");
holiday.setDate(Calendar.getInstance().getTime());
holiday.setFirstDay(new SimpleDateFormat("dd-MM-yyyy").parse(holiday.getStringFirstDay()));
holiday.setLastDay(new SimpleDateFormat("dd-MM-yyyy").parse(holiday.getStringLastDay()));
holiday.setNumberOfDays(Util.calculateNumberOfDays(holiday.getFirstDay(), holiday.getLastDay()));
holiday.setUser(userDao.findByUserName(Util.getLoggedInUserName()));
List<Holiday> lstHoliday = holidayDao.findByUser(userDao.findByUserName(Util.getLoggedInUserName()));
if(holiday.getNumberOfDays()> Util.calculateResidualHoliday(lstHoliday))
{
redirectAttrs.addAttribute("hasError", true);
redirectAttrs.addAttribute("errorMessage", "Die Anzahl an Urlaubstagen ist größer als Ihr Resturlaub !!");
return "forward:/user/holiday";
}
holidayDao.save(holiday);
return "redirect:/user/holiday";
}
The funny thing is , the redirect works when the holiday can be saved. It only does not work when there is an error so it is in the if block.

How to get Response of REST API in JSON format by Default in Magento

In magento as we use the REST url to access the data,as http://localhost/magemto/api/rest/products it returns in XML format.
But as my team requirement, I should send the data in JSON format to access AJAX calls easily.. I have used REST client to include a header as 'Content-Type:appilcation/json'.. Then it returns in JSON format.. But I want it as defaultly by the magento API..
Hey, I do have a solution for this, I would like to share with you.
First go to your magento root folder then go to following path
\app\code\core\Mage\Api2\Model\Request.php
Go to the method getAccepTypes() and change with this code below it will fulfill your requirement.
public function getAcceptTypes()
{
$qualityToTypes = array();
$orderedTypes = array();
foreach (preg_split('/,\s*/', $this->getHeader('Accept')) as $definition) {
$typeWithQ = explode(';', $definition);
$mimeType = trim(array_shift($typeWithQ));
// check MIME type validity
if (!preg_match('~^([0-9a-z*+\-]+)(?:/([0-9a-z*+\-\.]+))?$~i', $mimeType)) {
continue;
}
$quality = '1.0'; // default value for quality
if ($typeWithQ) {
$qAndValue = explode('=', $typeWithQ[0]);
if (2 == count($qAndValue)) {
$quality = $qAndValue[1];
}
}
$qualityToTypes[$quality][$mimeType] = true;
}
krsort($qualityToTypes);
foreach ($qualityToTypes as $typeList) {
$orderedTypes += $typeList;
}
unset($orderedTypes);
$orderedTypes=Array
("application/json" => 1);
return array_keys($orderedTypes);
}
Hope this help you.

How to perform a get request with RestSharp?

I'm having trouble figuring out how to make a GET request using RestSharp on Windows Phone 7. All of the examples show making a POST request, but I just need GET. How do I do this?
GET is the default method used by RestSharp, so if you don't specify a method, it will use GET:
var client = new RestClient("http://example.com");
var request = new RestRequest("api");
client.ExecuteAsync(request, response => {
// do something with the response
});
This code will make a GET request to http://example.com/api. If you need to add URL parameters you can do this:
var client = new RestClient("http://example.com");
var request = new RestRequest("api");
request.AddParameter("foo", "bar");
Which translates to http://example.com/api?foo=bar
What you're looking for is located here.
The code snippet that covers your scenario is below (request.Method should be set to Method.GET):
public void GetLabelFeed(string label, Action<Model.Feed> success, Action<string> failure)
{
string resource = "reader/api/0/stream/contents/user/-/label/" + label;
var request = GetBaseRequest();
request.Resource = resource;
request.Method = Method.GET;
request.AddParameter("n", 20); //number to return
_client.ExecuteAsync<Model.Feed>(request, (response) =>
{
if (response.ResponseStatus == ResponseStatus.Error)
{
failure(response.ErrorMessage);
}
else
{
success(response.Data);
}
});
}

How to use Zend Framework Form Hash (token) with AJAX

I have included Zend_Form_Element_Hash into a form multiplecheckbox form. I have jQuery set to fire off an AJAX request when a checkbox is clicked, I pass the token with this AJAX request. The first AJAX request works great, but the subsequent ones fail.
I suspect it may be once the token has been validated it is then removed from the session (hop = 1).
What would be your plan of attack for securing a form with Zend Framework Hash yet using AJAX to complete some of these requests?
I finally abandoned using Zend_Form_Element_Hash and just created a token manually, registered it with Zend_Session and then checked it upon submission.
form.php
$myNamespace = new Zend_Session_Namespace('authtoken');
$myNamespace->setExpirationSeconds(900);
$myNamespace->authtoken = $hash = md5(uniqid(rand(),1));
$auth = new Zend_Form_Element_Hidden('authtoken');
$auth->setValue($hash)
->setRequired('true')
->removeDecorator('HtmlTag')
->removeDecorator('Label');
controller.php
$mysession = new Zend_Session_Namespace('authtoken');
$hash = $mysession->authtoken;
if($hash == $data['authtoken']){
print "success";
} else {
print "you fail";
}
This seems to work and still keeps things relatively sane and secure. I'd still rather use the Hash element, but I can't seem to make it work with AJAX.
Thanks all.
That's how to handled hash field in ajax form :
class AuthController extends Zend_Controller_Action
{
public function init()
{
$contextSwitch = $this->_helper->getHelper('contextSwitch');
$contextSwitch->addActionContext('index', 'json')
->initContext();
}
public function loginAction()
{
$form = new Application_Form_Login();
$request = $this->getRequest();
if ($request->isPost()) {
if ($form->isValid($request->getPost())) {
// some code ..
} else {
// some code ..
// Regenerate the hash and assign to the view
$reservationForm->hash->initCsrfToken();
$this->view->hash = $reservationForm->hash->getValue();
}
}
$this->view->form = $form;
}
}
And then in your view script ..
<? $this->dojo()->enable()
->requireModule('dojox.json.query')
->onLoadCaptureStart() ?>
function() {
var form = dojo.byId("login_form")
dojo.connect(form, "onsubmit", function(event) {
dojo.stopEvent(event);
var xhrArgs = {
form: this,
handleAs: "json",
load: function(data) {
// assign the new hash to the field
dojo.byId("hash").value = dojox.json.query("$.hash", data);
// some code ..
},
error: function(error) {
// some code ..
}
}
var deferred = dojo.xhrPost(xhrArgs);
});
}
<? $this->dojo()->onLoadCaptureEnd() ?>
Hope it's not too late :D
There is a solution:
Create, besides the form that will contain the data, a form without elements. From the controller you instantiate the two forms. Also in the controller, you add the element hash to the empty form. Both forms should be sent to the vision. Then, in the condition "if ($ request-> isXmlHttpRequest ())" in the controller you render the empty form. Then, you take the hash value with the method "getValue ()". This value must be sent in response by Ajax and then use JavaScript to replace the hash value that is already obsolete. The option to create an empty form for the hash is to avoid problems with other elements such as captcha that would have its id generated again if the form were rendered, and would also need to have the new information replaced. The validation will be done separately because there are two distinct forms. Later you can reuse the hash (empty) form whenever you want. The following are examples of the code.
//In the controller, after instantiating the empty form you add the Hash element to it:
$hash = new Zend_Form_Element_Hash('no_csrf_foo');
$hash_form->addElement('hash', 'no_csrf_foo', array('salt' => 'unique'));
//...
//Also in the controller, within the condition "if ($request->isXmlHttpRequest())" you render the form (this will renew the session for the next attempt to send the form) and get the new id value:
$hash_form->render($this->view);
$hash_value['hash'] = $hash_form->getElement('no_csrf_foo')->getValue();//The value must be added to the ajax response in JSON, for example. One can use the methods Zend_Json::decode($response) and Zend_Json::encode($array) for conversions between PHP array and JSON.
//---------------------------------------
//In JavaScript, the Ajax response function:
document.getElementById("no_csrf_foo").value = data.hash;//Retrieves the hash value from the Json response and set it to the hash input.
Leo
Form hashes are great in principle and a bit of a nightmare in practice. I think the best way to handle this is to return the new hash with the response when you make a request, and update the form markup or store in memory for your javascript as appropriate.
The new hash may be available from the form object, or you can read it from the session.
You hinted at the right answer in your question: increase the hop count.
There was specific mention of this in the ZF manual online, but they updated their manuals and now i can't find it (grin)- otherwise i would have posted the link for you.
If you want to use form validator in ajax side use following code :
Myform.php
class Application_Form_Myform extends Zend_Form
{
# init function & ...
public function generateform($nohash = false)
{
# Some elements
if(!$nohash)
{
$temp_csrf = new Zend_Session_Namespace('temp_csrf');
$my_hash = new Zend_Form_Element_Hash ( 'my_hash' );
$this->addElement ( $my_hash , 'my_hash');
$temp_csrf->hash = $my_hash->getHash();
}
# Some other elements
}
}
AjaxController.php
class AjaxController extends Zend_Controller_Action
{
// init ...
public function validateAction()
{
# ...
$temp_csrf = new Zend_Session_Namespace('temp_csrf');
if($temp_csrf->hash == $params['received_hash_from_client'])
{
$Myform = new Application_Form_Myform();
$Myform->generateform(true);
if($AF_Bill->isValid($params))
{
# Form data is valid
}else{
# Form invalid
}
}else{
# Received hash from client is not valid
}
# ...
}
}

Resources