Ok, I finally did it and here is how the future reader (you) can do it too. Since nobody responded to my original request I'm assuming it might be the only way to do it for now:
- Edit bootstrap/autoload.php and add the following:
require __DIR__.'/../app/Http/helpers.php'; // Add this line
require __DIR__.'/../vendor/autoload.php';
- Create a new file called: app/Http/helpers.php and add the following code:
<?php
/**
* We supply our own instance of the response in order to load
* our own response class when the response() helper is called.
*
* @param string $content
* @param int $status
* @param array $headers
*
* @return \App\Http\JsonResponse
*/
function response($content = '', $status = 200, array $headers = [])
{
$factory = app('App\Http\ResponseFactory');
if (func_num_args() === 0) {
return $factory;
}
return $factory->make($content, $status, $headers);
}
The above code basically declares the response() function so that when laravel's own helpers are created directly afterwards it will not declare a new one but use ours instead.
- Create a new file called: app/Http/ResponseFactory.php and add the following code:
<?php
namespace App\Http;
use JsonSerializable;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Routing\ResponseFactory as BaseFactory;
class ResponseFactory extends BaseFactory
{
/**
* Return a new JSON response from the application.
*
* @param string|array $data
* @param int $status
* @param array $headers
* @param int $options
* @return \App\Http\JsonResponse
*/
public function json($data = [], $status = 200, array $headers = [], $options = 0)
{
if ($data instanceof Arrayable && ! $data instanceof JsonSerializable) {
$data = $data->toArray();
}
return new JsonResponse($data, $status, $headers, $options);
}
}
Here we declare our own factory that will return our own JsonResponse instance when used. The JsonResponse class is created next...
- Create a new file called: app/Http/JsonResponse.php and add the following code:
<?php
namespace App\Http;
use Illuminate\Http\JsonResponse as BaseResponse;
class JsonResponse extends BaseResponse
{
const HTTP_AUTHENTICATION_TIMEOUT = 419;
const HTTP_USER_NOT_FOUND = 425;
const HTTP_TOKEN_INVALID = 498;
const HTTP_TOKEN_REQUIRED = 499;
public static $statusTexts = [
419 => 'Authentication Timeout',
425 => 'User Not Found',
498 => 'Token Invalid',
499 => 'Token Required'
];
/**
* Sets the response status code.
*
* @param int $code HTTP status code
* @param mixed $text HTTP status text
*
* If the status text is null it will be automatically populated for the known
* status codes and left empty otherwise.
*
* @return Response
*
* @throws \InvalidArgumentException When the HTTP status code is not valid
*/
public function setStatusCode($code, $text = null)
{
$this->statusCode = $code = (int) $code;
if ($this->isInvalid()) {
throw new \InvalidArgumentException(sprintf('The HTTP status code "%s" is not valid.', $code));
}
if (null === $text) {
if (isset(self::$statusTexts[$code])) {
$this->statusText = self::$statusTexts[$code];
} else if (isset(parent::$statusTexts[$code])) {
$this->statusText = parent::$statusTexts[$code];
} else {
$this->statusText = 'Unknown Status';
}
return $this;
}
if (false === $text) {
$this->statusText = '';
return $this;
}
$this->statusText = $text;
return $this;
}
}
This file overrides the Illuminate\Http\JsonResponse class which in turn overrides the Symfony\Component\HttpFoundation\JsonResponse class. We need to append our own response codes and status texts here, as an example I have added code 499 Token Required and a few others but you can add more or replace them. We then have to also override the setStatusCode() method so that we can check our own array as well as that of the parent class.
- Finally, to return a JSON response with you own new code you can do the following in your controller:
return response()->json(['foo' => 'bar'], 499);
I hope this helps anyone in the same situation as I am.