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;
}
Related
I am working with 2.6.1 version of CakePHP. I have created one controller named as AndroidController.php and that looks like
<?php
class AndroidController extends AppController {
public function survey_question()
{
Configure::write('debug', '2');
$survey_id = $_REQUEST['survey_id'];
$this->layout = "";
//$condition = "Question.survey_id = '".$survey_id."'";
$info = $this->Question->find('all', array(
'conditions' => array(
"Question.survey_id" => $survey_id /*dont use array() */
)
));
echo json_encode($info);
exit;
}
}
?>
So, it gives an error like
Error: The action admin_survey_question is not defined in controller
AndroidController
Error:Create AndroidController::admin_survey_question() in file: app/Controller/AndroidController.php.
Note :My website url is
http://navyon.com/dev/mt/admin/android/survey_question?survey_id=2
So how can I resolve this?
You have enable admin routing for that action so your action should preceded admin_
Then your action look like below:
<?php
class AndroidController extends AppController {
public function admin_survey_question()
{
Configure::write('debug', '2');
$survey_id = $_REQUEST['survey_id'];
$this->layout = "";
//$condition = "Question.survey_id = '".$survey_id."'";
$info = $this->Question->find('all', array(
'conditions' => array(
"Question.survey_id" => $survey_id /*dont use array() */
)
));
echo json_encode($info);
exit;
}
}
?>
If you don't want enable admin routing for that action then remove admin from url and access like this :
http://navyon.com/dev/mt/android/survey_question?survey_id=2
I am using Zend 1.12
I have a form which has two fields: email, and file
My index view shows the form. And after validation is successful, I want to parse the csv file and show the content on result view:
My Code:
IndexController:
class IndexController extends Zend_Controller_Action {
public function init() {
/* Initialize action controller here */
}
public function indexAction() {
// action body
$form = new Application_Form_FileUpload();
$form->submit->setLabel('Upload');
$this->view->form = $form;
if ($this->getRequest()->isPost()) {
$formData = $this->getRequest()->getPost();
if ($form->isValid($formData)) {
$file = $form->getValue('file');
$email = $form->getValue('email');
//$this->_helper->viewRenderer('result', null, true);
//$this->_helper->redirector('result', 'index','', array('email' => $email, 'file' => $file));
$this->_helper->redirector->gotoRouteAndExit (array(
'controller' => 'index',
'action' =>'result',
'name' => $file));
} else {
$form->populate($formData);
}
}
}
public function resultAction() {
$email = $this->_getParam('name');
$this->view->email = $email;
}
}
My index view:
<?php
$this->form->setAction($this->url(array('action' => 'index')));
echo $this->form;
?>
My result view:
<?php
echo $this->email;
//echo the content of the csv file;
?>
My result view is empty always.
What is the correct/right way to get the form data, and if validation is successful, show the content in result view.
Edit: I have succeeded to get parameters passed to resultaction.
I just was looking into different file. That is why it was not showing up.
But still, is it the right way to do it for my case? For it seems not correct.
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);
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;
}
I want standartise all JSON responses ( something like Standardised JSON response from views ).
Here is JSON response example
{
"status" : "failure",
"errors" : {
"name" : [ "Error text 1", "Error text 2" ],
"email" : [ "Email error text" ]
}
}
And here is class implementing my standartised JSON response
class JsonResponse
{
protected $_errors = array();
public function addError($key, $value) {
$this->_errors[$key][] = $value;
return $this;
}
public function setFormErrors(Zend_Form_Abstract $form) {
$this->_errors = $form->getErrors();
return $this;
}
public function __toArray() {
if (!empty($this->errors)) {
return array(
'status' => 'fail',
'errors' => $errors,
);
}
return array(
'status' => 'success',
);
}
public function __toString() {
return json_encode($this->__toArray());
}
}
Everything is great, but using this class is real pain in the ass.
class App_Controller extends Zend_Action_Controller
{
public function submitAction()
{
$form = new App_Form();
$form->isValid($this->getRequest()->getPost());
//disabling displaying layout
$this->_helper->layout()->disableLayout();
$this->_helper->viewRenderer->setNoRender(true);
$response = new JsonResponse();
$response->setFormErrors($form);
echo $response;
}
}
I'm real noob in Zend Framework.
What is the best way to wrap JsonResponse to?
helper
extend Zend_Controller_Response_Abstract
new context switch
implement in Form
What is the best approach?
Creating a custom JSON response object with Zend Action Helper ContextSwitch - nice way of doing it, but still requires too much code, imho.
IMO you should use a context switch (JSON or your own) and use your preferred way to format your response data structure.
It seems like you are implementing the ajax form validation aren't you ? Maybe you should have a look on this : Zend form ajax validation on submit (and ask google about processAjax())