I'm attempting to update records through decoded JSON by ID in this CakePHP function:
public function update() {
$this->layout = 'ajax';
if($this->request->is('post')) {
$decoded = json_decode($this->request->data,true);
if($data = $this->Foobar->save($decoded)) {
$data = json_encode(array(
"message" => "Foobar successfully updated.",
"update" => $this->request->data
));
} else {
$data = json_encode(array(
"message" => "Foobar could not be updated.",
"update" => $decoded,
"updateJson" => $this->request->data
));
}
} else {
$data = json_encode(array(
"message" => "Method should be post."
));
}
$this->set('data', $data);
But the decode keeps returning null:
{"message":"Foobar could not be updated.","update":null,"updateJson":{"ID":"1","status":2}}
However, if I go to http://www.compileonline.com/execute_php_online.php and enter:
<html><head></head><body>
<pre>
<?php
print_r(json_decode('{"ID":"1","status":2}', true));
?>
</pre>
</body></html>
It works just fine...
Looking at related questions...
I've seen suggestions to try json_last_error(), this returns 0 for me.
I've seen someone mention magic_quotes might be on, mine are off.
I've seen suggestions to use json_decode(utf8_encode($this->request->data),true);, this still returns null for me
Any ideas?
I don't think you should JSON Decode the data.
Try to directly save:
$data = $this->Foobar->save($this->request->data);
Related
I am new at PHP. We are creating REST API in Phalcon and I've created a put request. It already works, but I would like to check if update has really happened before sending a success response. So I've created a conditional for that ( if (!$product->update()) ), but it always returns 'true'. How can I check if any field has changed in a record?
public function put()
{
$id = $this->getParam('id');
$input = $this->getRawData();
$product = Product::findFirst([
'conditions' => 'id = :id:',
'bind' => ['id' => $id]
]);
if ($product === null){
throw new NotFoundException();
}
$product->assign($input);
$product->update();
if (!$product->update()) {
$this->errorResponse($product->getMessages());
} else {
$this->successResponse($product->toArray($product->update()));
}
}
You can use Model Events, i.e. afterUpdate and notSaved, like:
use Phalcon\Mvc\Model;
use Phalcon\Http\Response;
class ModelBase extends Model
{
public function afterUpdate()
{
$response = new Response();
$response->setJsonContent([
'success' => true,
'message' => "Record updated"
])->send();
}
public function notSaved()
{
$response = new Response();
$response->setJsonContent([
'success' => false,
'message' => 'Record not saved'
])->send();
}
}
The Product and all other models will extend ModelBase. Then your code could be:
public function put()
{
$id = $this->getParam('id');
$input = $this->getRawData();
$product = Product::findFirst([
'conditions' => 'id = :id:',
'bind' => ['id' => $id]
]);
if ($product === null){
throw new NotFoundException();
}
$product->assign($input);
$product->update();
}
And Phalcon event will respond if the model was updated or not. If you prefer, you can also use custom http response codes for update or notSaved. More information about Model Events in the documentation
You are calling $product->update() three times. You do it once after the assign, then again for your if test, which is why it's always returning TRUE there I believe, and once inside the toArray() which may not actually return anything since the second and third updates don't have any data to update (not sure about that though).
I would code this as follows:
$product->assign($input);
$results = $product->update();
if (!results) {
$this->errorResponse($product->getMessages());
} else {
$this->successResponse($results->toArray());
}
I am assuming that the $product->assign($input); statement is working as expected to update the $product data for you. I don't use that. I prefer to do direct assignments for updates so nothing is left to chance, ie. $product->whatever = $input['whatever'];.
Give this a try and hopefully it will work as expected for you.
I have two routes.
Route::get('/receiveSignal', 'SignalController#receiveSignal');
Route::get('/sendSignal', 'SignalController#sendSignal');
I want to simulate sending data from sendSignal to receiving signal route.
So, in sending signal function I have this:
public function sendSignal()
{
$data = ['spotid' => '421156', 'name' => 'Test', 'desc' => 'some desc', 'StartofDetection' => '2018-01-17 22:22:22'];
$dataJson = json_encode($data);
return $dataJson;
}
How can I change it to receive in receiveSignal like this:
public function receiveSignal()
{
$test = file_get_contents('php://input');
dd($test);
}
Here I should receive the json to the receiveSignal after I enter the http://localhost:8000/sendSignal. Is this possible at all?
Try something like this:
1. In your route:
Route::post('receiveSignal', 'SignalController#receiveSignal');
Route::get('sendSignal', 'SignalController#sendSignal');
In your sendSignal method
public function sendSignal()
{
$data = ['key' => 'value', 'key2' => 'value2'];
$response = http_post_fields('http://localhost:8000/receiveSignal', $data);
if (!empty($response)) {
return view('success'); // or anything else you want to return
}
else {
return view('failed');
}
}
In your receiveSignal method
public function receiveSignal(Request $request)
{
$key = $request->input('key');
$key1 = $request->input('key2');
//and so on
}
Good luck.
I'm stuck at updating table row using api in codeigniter,
i already have read tutorial from code tutsplus
but there's no spesific to do it,
so i tried by myself and got stuck :-(
url request:
http://localhost/work/bnilife/v1/signup/user/post?nopol=a1b2c3d4e5&username=agus&password=kucingtikus&captcha=c12ds
Here's the json respon:
{
"error": "error :-( "
}
My Controller look like this below:
public function user_post()
{
date_default_timezone_set('Asia/Jakarta');
$datestring ="%Y-%m-%d %H:%i:%s";
$time =time();
$datetime =mdate($datestring, $time);
$data = array (
'nopol' => $this->input->get_post('nopol'),
'username' => $this->input->get_post('username'),
'password' => sha1($this->input->get_post('password')),
'created_at' => $datetime,
'updated_at' => $datetime
);
$result = $this->signup_m->signup_insert($data);
if($result) {
$this->response($data, 200);
} else {
$this->response(array('error' => 'error :-( '),400);
}
}
My model:
public function signup_insert($data) {
// Query to check whether username already exist or not
$condition = "nopol=" . "'" . $data['nopol'] . "'" ;
$this->db->where($condition);
$this->db->update('user', $data); }
Is there any something wrong or misstype,
thank you guys
i'm new at this stuff.
You can check codeigniter documentation how are working Database methods http://www.codeigniter.com/userguide3/database
public function signup_insert($data) {
$this->db->where('nopol',$data['nopol']);
return $this->db->update('user', $data);
}
In your case you need and return else you can't use the method as $result as it will be equal to NULL..
Check and CI Form Validation library as you don't validate your input data (even escaped) it may generate problems.
And importantly, you should write proper method names: signup_insert should INSERT not UPDATE.
'nopol' => $this->input->get_post('nopol') in this change to 'nopol' => $this->input->get_post('no_polis'),
also $this->db->where($condition) $condition is not defined.
Like #svetlio said,
i add some solution if nopol is typo(misstype) or null.
it will return false,
so i add some code to do it.
like this below:
if ($this->db->affected_rows() === 1) {
return true;
} else {
return false;
}
}
so it wont be like:
return $this->db->update('user', $data);
I want to send an xml response from my a controller action of cakephp. I have been trying to follow the official guide: http://book.cakephp.org/2.0/en/views/json-and-xml-views.html
But i keep getting this error:
Missing View
Error: The view for ServicesController::index() was not found.
this is what my services controller looks like:
<?php
class ServicesController extends AppController {
var $uses = array();
var $components = array('Auth','Session','RequestHandler');
function beforeFilter() {
$this->Auth->allow('index');
}
function index(){
$output = array(
"status" => "OK",
"message" => "You are good"
);
$this->set('output', $output );
$this->set('_serialize', array("output"));
}
}
?>
I have also added the following line to my routes.php
Router::parseExtensions('json', 'xml');
what could be the thing that im doing wrong??
You can try to convert your array to XML, echo the output and exit the function:
function index(){
$output = array(
"root" => array( // It needs one top element (http://book.cakephp.org/2.0/en/core-utility-libraries/xml.html#transforming-an-array-into-a-string-of-xml)
"status" => "OK",
"message" => "You are good"
)
);
$xmlObject = Xml::fromArray($output);
echo $xmlObject->asXML();
exit;
}
I have been searching all over stackoverflow and Google for a solution to my problem.
I have created two projects with Zend Framework - Project1 and Project2 - and I want to implement web services on one of them. The idea is to send a JSON-string to Project1 and receive back a JSON with all the details associated with that variable using POST. Now I have created a TestController on Project2:
public function indexAction(){
$uri = 'http://project1.com/WebService/data';
$config = array(
'adapter' => 'Zend_Http_Client_Adapter_Curl',
'curloptions' => array(CURLOPT_FOLLOWLOCATION => true),
);
$client = new Zend_Http_Client($uri, $config);
$request = $client->request('POST');
print_r($request->getBody());
exit();
}
The above code works. It reads the dataAction from the Project1 controller and gives me an output of whatever is echoed. But when I try this:
public function indexAction(){
$uri = 'http://project1.com/WebService/data';
$config = array(
'adapter' => 'Zend_Http_Client_Adapter_Curl',
'curloptions' => array(CURLOPT_FOLLOWLOCATION => true),
);
$client = new Zend_Http_Client($uri, $config);
$data = array(
'userID' => 'TEST TEST',
'value' => 1,
'description' => 'ABCDEFG',
);
$request = $client->request('POST');
$json = json_encode($data);
$client->setRawData($json, 'application/json')->request('POST');
exit();
}
And on the server side when I try displaying inside dataAction:
public function dataAction(){
var_dump($this->getRequest()->getParam('var-name'));
var_dump($_POST);
die();
}
I get an output of this: NULL array(0) { } .... I get the same output when I try it on the client side. Also to mention.. I also tried opening the php://input file but got an empty string...
What am I missing??? I have frustrated myself searching on it since morning but got no solution.
Thanks in advance for response.
Here is what you are missing:
$json = json_encode($data);
$client->setRawData($json, 'application/json')->request('POST');
sends a POST request but the data in the POST body is not a url-encoded string, instead it is just raw JSON.
Calling $this->getRequest()->getParam('foo') looks at the PHP superglobals $_GET and $_POST which will not contain any of the JSON parameters. The reason it will be empty is because PHP couldn't parse the POST data since it was JSON and not HTTP url-encoded content.
The solution is to use something like this in the dataAction if you want to receive JSON data in the POST body.
$post = $this->getRequest()->getRawBody();
try {
$json = Zend_Json::decode($post);
// now access parameters from $json array
} catch (Zend_Json_Exception $ex) {
echo "Failed to decode request, POST did not contain valid JSON.";
}
Edit: Here is the full code you can mess with.
public function requestAction()
{
// CHANGE THIS
$uri = 'http://playground/zendapp/public/index/data';
$config = array(
'adapter' => 'Zend_Http_Client_Adapter_Curl',
'curloptions' => array(CURLOPT_FOLLOWLOCATION => true),
);
$client = new Zend_Http_Client($uri, $config);
$data = array(
'userID' => 'TEST TEST',
'value' => 1,
'description' => 'ABCDEFG',
);
$json = json_encode($data);
$resp = $client->setRawData($json, 'application/json')->request('POST');
var_dump($resp->getBody());
exit();
}
public function dataAction()
{
$post = $this->getRequest()->getRawBody();
try {
$json = Zend_Json::decode($post);
print_r($json);
} catch (Exception $ex) {
echo "failed to decode json";
}
exit;
}