CakePHP View with json format - json

I 'm going to make a CakePHP application which collaborates with a mobile application. Mobile application is going to query CakePHP app to check if some vouchers are valid or not. I need to change some of my views such that their outputs be in json format in order to be parsed by mobile application easily.
To be specific if mobile app calles example.com/vouchers/check/1234 Cake should return something like this as response: {"validity":"valid"} or {"validity":"invalid"} which is the result of checking the validity of voucher with id 1234.

Basically, you should use extensions when you expect non HTML responses (JSON in this case)
So request
/vouchers/check/1234.json
and use the JsonView as per docs and as per ajax-and-cakephp tutorial.
To sum it up:
Use this to allow json extension being enabled:
Router::parseExtensions();
Router::setExtensions(array('json', ...));
Don't forget to include the RequestHandler component in the controllers $components list.
Add this to your action:
$data = array(
'validity' => ...,
);
$this->set(compact('data')); // Pass $data to the view
$this->set('_serialize', 'data'); // Let the JsonView class know what variable to use

Related

Spring HATEOAS template link expansion

Using the HATEOAS links functionality which is great I am trying to output a templated url to highlight the filter params available to a user
Example controller method
#RequestMapping(value = "/persons", method = RequestMethod.GET, produces = "application/hal+json")
public PersonsResource getPersons (#RequestParam(required = false, value = "name") String name, #RequestParam(required = false, value = "age") Integer age) {
...
personsResource.add(ControllerLinkBuilder.linkTo(ControllerLinkBuilder.methodOn(PersonController.class).getPersons(name, age)).withSelfRel());
}
When this method is invoked with no parameters links appears
_links: {
self: {
href: "http://myserver:8080/persons"
}
}
But I'd like
href: "http://myserver:8080/persons?name={name}&age={age}
Even better if one param was supplied then
href: "http://myserver:8080/persons?name={name}&age=21
Icing on the cake would be query parameters of {...] to be ignored ?
Does anyone know if this is possible using the Spring HATEOAS api ? I have managed to code around this but it seems like a reasonable suggestion for the API ?
You could try AffordanceBuilder from spring-hateoas-ext as a drop-in replacement for ControllerLinkBuilder. It creates template variables for parameters you leave undefined in the linkTo-methodOn idiom.
It not only allows to create templates, but also gives you the full capabilities of a RFC 5988 Link and has knowledge about request bodies, so that one can render Hydra or Html or Siren Responses with form-style request descriptors from it.
Disclaimer: I'm the author of spring-hateoas-ext.
This has been addressed in the latest spring-hateoas version. You can check the following issue:
https://github.com/spring-projects/spring-hateoas/issues/169
You should be able to get the required templated URL using something like:
resource.add(linkTo(methodOn(Controller.class).method(null)).withSelfRel());
I guess, the framework is still pretty immature.
I have v.0.11.0.RELEASE and have the same issue.
When you don't supply parameter values you don't have template URL as a result of the ControllerLinkBuilder.linkTo(methodOn) invocation. It's just the way you said, base path from the method annotation.
But when you supply parameter values it's exactly like you say:
https://stackoverflow.com/some/service/path?name=SomeName&age=11
(in my case parameters are different, but the effect is the one you see here)
The 'conceptually correct' URL should be
https://stackoverflow.com/some/service/path{?name,age}
But Spring HATEOAS doesn't support this. Unless you want to append it yourself in the code. Which is really undesirable.
I checked the UriBuilder from JavaEE, it works the same way, no templating for query parameters supported.

Meteor.http.call (call URL API)

so I'm trying to make a call to a bible verse API in my Meteor application. I made a template with name="display", with a simple {{checkitout}} in the template.
Then for the template, I tried to make the call in its corresponding helper. It looks like this (in coffeescript, but Javascript readers should understand as well):
#Template.display.helpers
checkitout:->
result = Meteor.http.call("GET","http://labs.bible.org/api/passage=john%203:2&type=json")
console.log(result)
The URL is a JSON of a bible verse, but the problem is, the Meteor.http.call requires a third argument, a "callback" (because this is in the client folder). I read some documentation + examples and have no idea what it means.
Also, if I call it like this, is result exactly the JSON file, or do I need to fit it within a new hash? And what does a callback mean? Can someone give me an example?
As helpers are synchronous and API calls are not, you need to store the call result in a reactive variable and return it from the helper:
verse = "Loading..."
verseLoaded = false
verseDep = new Deps.Dependency()
Template.Display.checkItOut = ->
verseDep.depend()
unless verseLoaded
verseLoaded = true
Meteor.http.get "...", (error, result) ->
verse = "..."
verseDep.changed()
verse
On the client, the callback is required as you said. So this is something you could do to query an API and display the JSON result:
Template.Display.helpers
checkItOut: ->
Meteor.http.get 'https://graph.facebook.com/facebook', (error, result) ->
if not error
console.log result # display the the open graph result
Note 1: To use these functions, you need to add the HTTP package to your project with $ meteor add http. You can find further information in the documentation.
Note 2: In your situation, you cannot make an API call client-side due to the Access-Control-Allow-Origin Policy. So, the solution would be to use a method and make the call server-side.
# Client-side
Template.Display.helpers
checkItOut: ->
Meteor.call 'getBibleText', (error, result) ->
if not error
console.log result
# Server-side (server directory)
Meteor.methods
'getBibleText': ->
result = HTTP.get 'http://labs.bible.org/api/?passage=john%203:2&type=xml'
return result

CakePHP - How to paging with json data?

I'm training with CakePHP. Currently I have a problem.
I don't know how to paging with json data.
My application will call to API and receive JSON data.
The format look like
{"success":1,"films":[{"film_id":"384","title":"GROSSE WONDERFUL","description":"A Epic Drama of a Cat And a Explorer who must Redeem a Moose in Australia","release_year":"2006","language_id":"1","original_language_id":null,"rental_duration":"5","rental_rate":"4.99","length":"49","replacement_cost":"19.99","rating":"R","special_features":"Behind the Scenes","last_update":"2006-02-15 05:03:42"},{"film_id":"984","title":"WONDERFUL DROP","description":"A Boring Panorama of a Woman And a Madman who must Overcome a Butler in A U-Boat","release_year":"2006","language_id":"1","original_language_id":null,"rental_duration":"3","rental_rate":"2.99","length":"126","replacement_cost":"20.99","rating":"NC-17","special_features":"Commentaries","last_update":"2006-02-15 05:03:42"}]}
This is php code
$data = array('filmId' => $search_data['filmId'], 'filmTitle' => $search_data['filmTitle'], 'releaseYear' => $search_data['releaseYear'], 'rating' => $search_data['rating']);
$HttpSocket = new HttpSocket();
$records = $HttpSocket->post($apiFilmsByConditions, $data);
$records = json_decode($records, true);
I try to use paginate of CakePHP but it seems that this will get data from database, not from API.
This is API link http://oxuhandmade.com/api/get_all_films.php
Can you help me on this case?
Doesn't the API query the database? An API is an "Application programming interface", meaning that it allows you to operate on the database from the "outside", based on a simple interface, triggered by some requests. So there is no point in wanting to limit the results via API, but not via database.
To limit the results an API returns, you need to pass a parameter together with your request, process it in the backend, query the database with the desired limit, and return the results to whoever made the request. Or simply hardcode the desired limit on the API, if it doesn't need to be dynamic.
The Paginator from CakePHP makes this work a whole lot easier, you only have to feed it some conditions and parameters for paginating the results, and it does the magic for you.

Change the way CakePHP associate models

I'm trying to split out some JSON strings in order to be parsed by this RestKit's iPhone library, but CakePHP is splitting out an incompatible string. For example, the string below is what it's currently splitting out:
1. {"Question":{"id":"1","content":"Test","player_id":"1","points":"0","votes":"0","created":"0000-00-00 00:00:00"},"Player":{"id":"1","username":"player_test"}}
I need to have something like:
2. {"Question":{"id":"1","content":"Test","player_id":"1","points":"0","votes":"0","created":"0000-00-00 00:00:00","Player":{"id":"1","username":"player_test"}}}
Note that the Player response should be part of Question.
The way the models are setup on Cake is that 'Question' belongs to 'Player' which the latter hasMany 'Question'
I am looking for the proper way of telling Cake to output something like the response #2 above. Any suggestions?
You can use afterFind() callback of your Question model to nest the Player record inside the Question record. Or modify the results array as required after fetching. The various function of Hash class might help you in reformatting the array.
You can add a custom method to your Question model that returns the result in the desired format. This will keep your code clean and keep the data-processing/formatting logic in your Model (where it should be in most cases);
For example, inside your Question model:
public function getQuestionsForPlayer($playerId)
{
$results = $this->find('all', array(
'fields' => array(/* fields */),
'conditions' => array(/* ..... */
/* etc */
));
// Process your result to be in the right format
// Hash::extract() and other Hash:: methods
// may be helpful here as #ADmad mentioned
return $processedResult;
}
As ADmad mentioned, the Hash utility may be helpful. Documentation is located here:
http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html

Extend current API's in Magento to get items in JSON format

I am a beginner to Magento. I am trying to extend the current API classes in Magento to fulfill my requirements and retrieve data in JSON format. I need:
I need to get all stores in a website
I need to get all Categories and Subcategories in a specific store
I need to get all products in a specific Category.
All data retrieved should be in JSON format.
Any blog/Forum topic? Any kind of help?
Thanks in advance.
Please refer to this Magento wiki page http://www.magentocommerce.com/wiki/doc/webservices-api/custom-api#creating_custom_adapter_for_api.
Steps:
You need to create a new API Server Adapter that should implement Mage_Api_Model_Server_Adapter_Interface.
Create a controller that will run your api server adapter
Implement Mage_Api_Model_Server_Adapter_Interface::run() method for process JSON request and return result in JSON. See Mage_Api_Model_Server_Handler_Abstract for understanding Magento API workflow.
never been is such situation , but an idea came to mind is to invoke a SOAP service or XML-RPC , then convert whatever data needed to JSON.
Magento offers SOAP or XML-RPC web service to be automatically generated with specific roles for users, very useful.
That would be a better approach and it is not at all complicated. Refer to this to see.
http://www.magentocommerce.com/wiki/5_-_modules_and_development/web_services/additional_information
See here
https://github.com/app-z/magento-android-web-api
There is even Random Products list
Is it what you want?
//
// Random Products Items
//
// http://localhost/magento/web-api.php?route=feed/web_api/random&limit=4&key=key1
//
function random_products($limit){
$json = array('success' => true);
$products = Mage::getModel('catalog/product')->getCollection();
$products->addAttributeToSelect(array('name', 'thumbnail', 'price')); //feel free to add any other attribues you need.
Mage::getSingleton('catalog/product_status')->addVisibleFilterToCollection($products);
Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($products);
$products->getSelect()->order('RAND()')->limit($limit);
foreach($products as $product){
$json['products'][] = array(
'id' => $product->getId(),
'name' => $product->getName(),
'href' => $product->getProductUrl(),
'thumb' => (string)Mage::helper('catalog/image')->init($product, 'thumbnail'),
'pirce' => Mage::helper('core')->currency($product->getPrice(), true, false) //." ".$currencyCode,
);
}
return $json;
}
Inchoo has written a free REST, JSON, and AMF adapter for Magento. You can find it here: http://www.magentocommerce.com/magento-connect/inchoo-api.html