I'm going to develop a method inside my Prestashop module to fetch list of products and return the result as JSON. I have no problem to get list of products however I don't know to use which hooks and how to return JSON result instead of returning back to a Prestashop page.
The best way is to use a specific controller in your module. the result of the controller is available by an URL.
(Your controller class have to extend the "ModuleFrontController" class)
In your module controller, you should change the default constructor by:
public function __construct($response = array()) {
parent::__construct($response);
$this->display_header = false;
$this->display_header_javascript = false;
$this->display_footer = false;
}
And, in your "postProcess" method, simply echo the string you want, using this for example:
$json = json_encode( (array)$object );
Finally, in a template, you can generate a link to this controller using:
{$link->getModuleLink('mymodule', 'mycontrolleurname', [], true)}
Related
I have been some time without programing in Synfony and I have some doubts.
Is posible that and Action Controller return a variable (for example and integer) instead of a Response Object or Json Object.
What I need is call a function inside another function in a different Controller. If the 2 functions live in the same Controller it has no problem (like this):
class AController{
public function AAction(){
$var = $this->BAction(); //Do whatever I want with $var
return Response ("Hello");
}
public function BAction(){
return 34; //return an integer instead of a Response
}
}
THE PROBLEM IS when the BAction is in another Controller. If I use a forward, Symfony expect that BAction return a Response object or a Json array, but I only want to return a simple variale.
Is this posible?? Return a simple integer...
Thanks a lot!!
No a Action must return a Response Object. But if you have two controllers (that will say two different classes) then you could create a service.
app/config/config.yml
services:
app.my_ownservice:
class: AppBundle\Services\OwnService
arguments:
entityManager: "#doctrine.orm.entity_manager"
app/Services/OwnService.php
namespace AppBundle\Services;
use Doctrine\ORM\EntityManager;
class OwnService {
/**
*
* #var EntityManager
*/
private $em;
public function __constructor(EntityManager $entityManager)
{
$this->em = $entityManager;
}
public function doSomething(){
// you could use the entitymanager here
return 'Okay i will do something.';
}
}
And from each controller (or whatever) you can do:
$myOwnService = $this->get('app.my_ownservice');
$text = $myOwnService->doSomething();
// echo $text;
A controller should never use another controllers action. Thats not the problem that Controllers solve. Symfony business logic structure is SOA based. (https://en.wikipedia.org/wiki/Service-oriented_architecture) Therefore for custom business logic you should always use either:
Services: http://symfony.com/doc/current/book/service_container.html
Events: http://symfony.com/doc/current/components/event_dispatcher/introduction.html
I have a controller that is purely for API use (no view or layout).
I want every action to return JSON format and have the Content-Type in the response be application/json.
I could achieve the header part by using the controller postDispatch() but couldn't find a way to do json_encode() from single place (I know I can do it from every action however I wanted it to be centralized).
I have even tried to use a plugin and there to manipulate the request body but for some reason that is not clear to me it is always empty.
Currently my solution is as follows:
public function init()
{
// no Layout
$this->_helper->layout()->disableLayout();
// no views
$this->_helper->viewRenderer->setNoRender(true);
}
public function indexAction()
{
$data = array("likes","to","sleep");
echo Zend_Json::encode($data);
}
public function postDispatch()
{
$this->getResponse()->setHeader('Content-Type', 'application/json');
}
Now, if i only managed to do the echo Zend_Json::encode in one single place...
You can use the ContextSwitch action helper
The JSON context sets the 'Content-Type' response header to 'application/json', and the view script suffix to 'json.phtml'. By default, however, no view script is required. It will simply serialize all view variables, and emit the JSON response immediately.
You will need to register it within the controller.
class FooController extends \Zend_Controller_Action
{
public function init()
{
$contextSwitch = $this->_helper->getHelper('contextSwitch');
$contextSwitch->addActionContext('list', 'json')
->addActionContext('bar', 'json')
->initContext('json'); // json arg here means that we only allow json
}
}
You would then need to pass the format parameter in the url /module/foo/bar/format/json or as a query parameter ?format=json
You can create your own controller plugin.
In preDispatch turn off layout and view renderer and in postDispatch set content-type header in response.
Next option is to assing data to view.
public function indexAction() {
$data = array("likes","to","sleep");
$this->view->assign('data', $data);
}
and in view script call json view helper <?php echo $this->json($this->data); and do not use layout.
I have a little problem, I'm trying to send a json response, but all I get is a empty object all the time.
So here is my code:
//Get the data from DB
$template = $this->getDoctrine()
->getRepository('EVRYgroBundle:Template')
->findOneBy(
array('active' => 1)
);
if (!$template) {
throw $this->createNotFoundException(
'No product found for id '
);
}
//Send the response
$response = new Response();
$response->setContent(json_encode($template));
return $response;
And when I'm viewing it all it shows is {}
And I have also tried with the jsonResponse and with this code:
$response = new JsonResponse();
$response->setData($template);
And I have no idea what i'm doing wrong!
json_encode expects an array as first parameter to be given in. When you call it with an object the public properties will may be displayed. To keep the properties protected (as they should be) you can add a expose function to your entity:
/**
* delivers all properties and values of the entity easily
*
* #return array
*/
public function expose()
{
return get_object_vars($this);
}
and then call
$response->setData(json_encode($template->expose()));
This way you keep your entity clean with only access via getter and setter methods and you can access all properties via json still.
Well I found the problem, the problem was that some variables that holds the information from the db was set to protected and not public.
I'm trying to implement a RESTful api in Laravel, and I for my index I want to return all the tasks as json.
However, when I use
return Response::json(Task::all());
I get an error: "The Response content must be a string or object implementing __toString(), "boolean" given".
I get the same error when I use:
return Task::all();
I thought this was supposed to work? What am I doing wrong?
I double-checked to see if Task::all() actually returns anything, and it does. This code does work in another project, although on another server and maybe another php version?
Someone suggested to use toArray(), but I get the same result. Code:
<?php
class UserController extends BaseController {
public function index() {
$users = User::all();
$userArray = $users->toArray();
return Response::json($userArray);
}
}
Response::json function is expecting argument 1 to be an array. From the API:
json( string|array $data = array(), integer $status = 200, array $headers = array() )
Return a new JSON response from the application.
So you can't just pass through the results of your find, but instead use the toArray() function and pass that through instead:
$tasks = Task::all();
Response::json($tasks->toArray());
Edit ---
If you're working with a BLOB, then base64_encode it first. See this post.
Example:
base64_encode($user['image']);
I'm using Zend Framework 1 with the Bisna library to integrate Doctrine 2. I generated my Entities from my database model with the Doctrine 2 CLI. This is all working fine, except for the setter methods for associated records. The argument they accept must be of a specific namespace (\Category here).
class Article
{
public function setCategory(\Category $category = null) {
$this->category = $category;
return $this;
}
}
However, when I do this:
$article = $this->em->getRepository('\Application\Entity\Article')->find(1);
$category = new \Application\Entity\Category();
$category->SetName('New Category');
$article->setCategory($category);
I get the following fatal error: Argument 1 passed to Application\Entity\CategoryField::setCategory() must be an instance of Category, instance of Application\Entity\Category given.
When I change the setter method to accept \Application\Entity\Category objects, it's working of course. Should I do this for every generated method, or are there other options? This is the first time I'm using namespaces, so it might be something simple.
You can always add this to the top of your class file: use \Application\Entity\Category; and then simply reference it later like so: public function setCategory(Category $category = null)
Check out: http://php.net/manual/en/language.namespaces.importing.php for more info about use
Otherwise you would have to reference the full namespace otherwise your application does not know that \Category is a reference to \Application\Entity\Category