11<?php namespace Dingo \Api \Http ;
22
3+ use RuntimeException ;
34use Illuminate \Support \MessageBag ;
45use Illuminate \Support \Contracts \JsonableInterface ;
56use Illuminate \Support \Contracts \ArrayableInterface ;
89
910class Response extends \Illuminate \Http \Response {
1011
12+ /**
13+ * Array of registered formatters.
14+ *
15+ * @var array
16+ */
17+ protected static $ formatters = [];
18+
1119 /**
1220 * Make an API response from an existing Illuminate response.
1321 *
@@ -24,95 +32,83 @@ public static function makeFromExisting(\Illuminate\Http\Response $response)
2432 *
2533 * @return \Dingo\Api\Http\Response
2634 */
27- public function morph ()
35+ public function morph ($ format = ' json ' )
2836 {
29- $ this -> headers -> set ( ' content-type ' , ' application/json ' );
37+ $ formatter = static :: getFormatter ( $ format );
3038
31- return $ this ->morphJsonResponse ();
32- }
39+ $ response = $ this ->original ;
3340
34- /**
35- * Morph the response to it's JSON representation by checking the type
36- * of response that's going to be returned.
37- *
38- * @return \Dingo\Api\Http\Response
39- */
40- protected function morphJsonResponse ()
41- {
42- if ($ this ->original instanceof JsonableInterface)
41+ // First we'll attempt to format the response if it's either an Eloquent
42+ // model or an Eloquent collection.
43+ if ($ response instanceof EloquentModel)
4344 {
44- $ this -> content = $ this -> morphJsonableInterface ( $ this -> original );
45+ $ response = $ formatter -> formatEloquentModel ( $ response );
4546 }
46- elseif (is_string ( $ this -> original ) )
47+ elseif ($ response instanceof EloquentCollection )
4748 {
48- $ this -> content = $ this -> encode ([ ' message ' => $ this -> original ] );
49+ $ response = $ formatter -> formatEloquentCollection ( $ response );
4950 }
5051 else
5152 {
52- $ this ->content = $ this ->morphArrayableInterface ($ this ->original );
53-
54- if (is_array ($ this ->content ))
53+ // Next we'll attempt to format the response if it's a string,
54+ // an array or an object implementing ArrayableInterface,
55+ // an object implementing JsonableInterface or an
56+ // unknown type.
57+ if (is_string ($ response ))
5558 {
56- array_walk_recursive ($ this ->content , function (&$ value )
57- {
58- $ value = $ this ->morphArrayableInterface ($ value );
59- });
59+ $ response = $ formatter ->formatString ($ response );
60+ }
61+ elseif (is_array ($ response ) or $ response instanceof ArrayableInterface)
62+ {
63+ $ response = $ formatter ->formatArrayableInterface ($ response );
64+ }
65+ elseif ($ response instanceof JsonableInterface)
66+ {
67+ $ response = $ formatter ->formatJsonableInterface ($ response );
68+ }
69+ else
70+ {
71+ $ response = $ formatter ->formatUnknown ($ response );
6072 }
61-
62- $ this ->content = $ this ->encode ($ this ->content );
6373 }
6474
65- return $ this ;
66- }
75+ // Set the "Content-Type" header of the response to that which
76+ // is defined by the formatter being used.
77+ $ this ->headers ->set ('content-type ' , $ formatter ->getContentType ());
6778
68- /**
69- * If content implements the ArrayableInterface it will be morphed to its
70- * array value.
71- *
72- * @param array|\Illuminate\Support\Contracts\ArrayableInterface $content
73- * @return array
74- */
75- protected function morphArrayableInterface ($ content )
76- {
77- return $ content instanceof ArrayableInterface ? $ content ->toArray () : $ content ;
79+ // Directly set the property because using setContent results in
80+ // the original content also being updated.
81+ $ this ->content = $ response ;
82+
83+ return $ this ;
7884 }
7985
8086 /**
81- * If content implements the JsonableInterface it will be morphed to its
82- * JSON value.
87+ * Get the formatter based on the requested format type.
8388 *
84- * @param \Illuminate\Support\Contracts\JsonableInterface $content
85- * @return string
89+ * @param string $format
90+ * @return \Dingo\Api\Http\Format\FormatInterface
91+ * @throws \RuntimeException
8692 */
87- protected function morphJsonableInterface ( $ content )
93+ public static function getFormatter ( $ format )
8894 {
89- if ($ content instanceof EloquentModel )
95+ if ( ! isset ( static :: $ formatters [ $ format ]) )
9096 {
91- $ key = $ content ->getTable ();
92-
93- return $ this ->encode ([$ key => $ content ->toArray ()]);
97+ throw new RuntimeException ('Response formatter " ' .$ format .'" has not been registered. ' );
9498 }
95- elseif ($ content instanceof EloquentCollection)
96- {
97- $ key = str_plural ($ content ->first ()->getTable ());
9899
99- return $ this ->encode ([$ key => $ content ->toArray ()]);
100- }
101- else
102- {
103- return $ content ->toJson ();
104- }
100+ return static ::$ formatters [$ format ];
105101 }
106102
107103 /**
108- * Encode the content to its JSON representation .
104+ * Set the response formatters .
109105 *
110- * @param string $content
111- * @return string
106+ * @param array $formatters
107+ * @return void
112108 */
113- protected function encode ( $ content )
109+ public static function setFormatters ( array $ formatters )
114110 {
115- return json_encode ( $ content ) ;
111+ static :: $ formatters = $ formatters ;
116112 }
117113
118114}
0 commit comments