Last Updated: February 25, 2016
·
3.321K
· raphaelstolt

JSONP(ad) Silex responses via an after middleware

One approach to auto transform Silex responses into JSONP(adding) responses via an after middleware. It's based on the Content-Type of the original reponse coming from the matching application route.

<?php
use Symfony\Component\HttpFoundation\JsonResponse;

$app->after(function (Request $req, Response $res) {
 if ($req->get('jsonp_callback') !== null 
 && $req->getMethod() === 'GET')
 {
 $contentType = $res->headers->get(
 'Content-Type'
 );
 $jsonpContentTypes = array(
 'application/json',
 'application/json; charset=utf-8',
 'application/javascript',
 );
 if (!in_array($contentType, $jsonpContentTypes)) 
 {
 // Don't touch the response
 return;
 }
 if ($res instanceof JsonResponse) {
 $res->setCallBack($req->get('jsonp_callback'));
 } else {
 $res->setContent(
 $req->get('jsonp_callback') 
 . '(' . $res->getContent() . ');'
 );
 }
 }
});

Another approach would be to guard or compare the current route against a set of JSONPable route patterns, which might come from a configuration; which, however, need to be maintained.

Yet another approach provided by @igorwesome would be to use the native Symfony\Component\HttpFoundation\JsonResponse directly inside a matching route, I guess.

<?php 
use Silex\Application,
 Symfony\Component\HttpFoundation\JsonResponse,
 Symfony\Component\HttpFoundation\Request;

$app->get('/ex', function(Application $a, Request $r) {
 if ($r->get('jsonp_callback') !== null 
 && $r->getMethod() === 'GET')
 {
 $data = $a['service_xy']->getDataXyz();
 $resp = new JsonResponse($data);
 return $resp->setCallback(
 $r->get('jsonp_callback')
 );
 }
});