Skip to content

Instantly share code, notes, and snippets.

@Ellrion
Last active January 18, 2018 18:47
Show Gist options
  • Save Ellrion/2c7648d3ebdef2cd8ed24ffa78cf1d3d to your computer and use it in GitHub Desktop.
Save Ellrion/2c7648d3ebdef2cd8ed24ffa78cf1d3d to your computer and use it in GitHub Desktop.
<?php
namespace App\Services\Foundation;
use Illuminate\Contracts\Container\Container;
use Illuminate\Contracts\Support\Jsonable;
use InvalidArgumentException;
use JsonSerializable;
class JsonFactory
{
/**
* Base Namespace for JsonGenerator classes.
*
* @var
*/
protected $rootNamespace;
/**
* @var \Illuminate\Contracts\Container\Container
*/
private $app;
/**
*
* @param \Illuminate\Contracts\Container\Container $app
*/
public function __construct(Container $app)
{
$this->app = $app;
}
/**
* Generate (transform) json from data.
*
* @param string $generator
* @param mixed $data
* @param int $options
* @return string
*/
public function make($generator, $data, $options = 0)
{
$generatorClass = $this->getGeneratorClass($generator);
$generator = $this->app->make($generatorClass, compact('data'));
if ($generator instanceof JsonSerializable) {
return json_encode($generator->jsonSerialize(), $options);
}
if ($generator instanceof Jsonable) {
return $generator->toJson($options);
}
throw new InvalidArgumentException('Builder must implements \Illuminate\Contracts\Support\Jsonable or \JsonSerializable');
}
/**
* Getting name of generator class.
*
* @param $generator
* @return string
*/
protected function getGeneratorClass($generator)
{
if (class_exists($generator)) {
return $generator;
}
$path = collect(explode('.', $generator))->map(function ($str) {
return ucfirst(camel_case($str));
});
return $this->rootNamespace . '\\' . implode('\\', $path->all());
}
/**
* Setting up root namespace for generators classes.
*
* @param $rootNamespace
* @return $this
*/
public function setRootGeneratorNamespace($rootNamespace)
{
$this->rootNamespace = $rootNamespace;
return $this;
}
}
<?php
namespace App\Providers;
use App\Services\Foundation\JsonFactory;
use Illuminate\Support\ServiceProvider;
class JsonViewServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
}
/**
* Register any application services.
*
* @return void
*/
public function register()
{
$this->app->singleton(['json.factory' => JsonFactory::class], function ($app) {
return (new JsonFactory($app))->setRootGeneratorNamespace('App\\Http\\JsonResponses');
});
$this->registerResponseBuilder();
}
/**
* Register a macros for response factory.
*/
protected function registerResponseBuilder()
{
$this->app->extend('Illuminate\Contracts\Routing\ResponseFactory', function ($factory, $app) {
$factory->macro(
'jsonable',
function ($generator, $data = [], $status = 200, array $headers = [], $options = 0) use ($app) {
return $this->json([], $status, $headers, $options)
->setJson($app['json.factory']->make($generator, $data, $status, $options));
}
);
return $factory;
});
}
}
<?php
namespace App\Http\JsonResponses;
use Illuminate\Contracts\Support\Jsonable;
class Simple implements Jsonable
{
protected $data;
/**
* Simple constructor.
* @param mixed $data
*/
public function __construct($data)
{
$this->data = $data;
if (method_exists($this, 'generate')) {
$this->data = $this->{'generate'}($data);
}
}
public function toJson($options = 0)
{
return $this->data;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment