1313class JsonApiParser extends JsonParser
1414{
1515 /**
16- * @var array|callable|null
16+ * Converts 'type' member to form name
17+ * If not set, type will be converted to singular form.
18+ * For example, 'articles' will be converted to 'Article'
19+ * @var callable
1720 */
18- protected $ formNameCallback ;
19-
20- public function __construct ($ formNameCallback = null )
21- {
22- if ($ formNameCallback === null ) {
23- $ formNameCallback = [$ this , 'typeToFormName ' ];
24- }
25- if (!is_callable ($ formNameCallback , true )) {
26- throw new InvalidConfigException ('JsonApiParser::formNameCallback should be callable ' );
27- }
28-
29- $ this ->formNameCallback = $ formNameCallback ;
30- }
21+ public $ formNameCallback ;
3122
23+ /**
24+ * Converts member names to variable names
25+ * If not set, all special characters will be replaced by underscore
26+ * For example, 'first-name' will be converted to 'first_name'
27+ * @var callable
28+ */
29+ public $ memberNameCallback ;
3230
3331 /**
3432 * Parse resource object into the input data to populates the model
@@ -38,9 +36,9 @@ public function parse($rawBody, $contentType)
3836 {
3937 $ array = parent ::parse ($ rawBody , $ contentType );
4038 if ($ type = ArrayHelper::getValue ($ array , 'data.type ' )) {
41- $ formName = call_user_func ( $ this ->formNameCallback , $ type );
39+ $ formName = $ this ->typeToFormName ( $ type );
4240 if ($ attributes = ArrayHelper::getValue ($ array , 'data.attributes ' )) {
43- $ result [$ formName ] = $ attributes ;
41+ $ result [$ formName ] = array_combine ( $ this -> parseMemberNames ( array_keys ( $ attributes)), array_values ( $ attributes )) ;
4442 } elseif ($ id = ArrayHelper::getValue ($ array , 'data.id ' )) {
4543 $ result [$ formName ] = ['id ' => $ id , 'type ' => $ type ];
4644 }
@@ -49,12 +47,12 @@ public function parse($rawBody, $contentType)
4947 if (isset ($ relationship [0 ])) {
5048 foreach ($ relationship as $ item ) {
5149 if (isset ($ item ['type ' ]) && isset ($ item ['id ' ])) {
52- $ formName = call_user_func ( $ this ->formNameCallback , $ item ['type ' ]);
50+ $ formName = $ this ->typeToFormName ( $ item ['type ' ]);
5351 $ result [$ name ][$ formName ][] = $ item ;
5452 }
5553 }
5654 } elseif (isset ($ relationship ['type ' ]) && isset ($ relationship ['id ' ])) {
57- $ formName = call_user_func ( $ this ->formNameCallback , $ relationship ['type ' ]);
55+ $ formName = $ this ->typeToFormName ( $ relationship ['type ' ]);
5856 $ result [$ name ][$ formName ] = $ relationship ;
5957 }
6058 }
@@ -63,16 +61,35 @@ public function parse($rawBody, $contentType)
6361 $ data = ArrayHelper::getValue ($ array , 'data ' , []);
6462 foreach ($ data as $ relationLink ) {
6563 if (isset ($ relationLink ['type ' ]) && isset ($ relationLink ['id ' ])) {
66- $ formName = call_user_func ( $ this ->formNameCallback , $ relationLink ['type ' ]);
64+ $ formName = $ this ->typeToFormName ( $ relationLink ['type ' ]);
6765 $ result [$ formName ][] = $ relationLink ;
6866 }
6967 }
7068 }
7169 return isset ($ result ) ? $ result : $ array ;
7270 }
7371
72+ /**
73+ * @param $type 'type' member of the document
74+ * @return string form name
75+ */
7476 protected function typeToFormName ($ type )
7577 {
78+ if ($ this ->formNameCallback !== null ) {
79+ return call_user_func ($ this ->formNameCallback , $ type );
80+ }
7681 return Inflector::id2camel (Inflector::singularize ($ type ));
7782 }
83+
84+ /**
85+ * @param array $memberNames
86+ * @return array variable names
87+ */
88+ protected function parseMemberNames (array $ memberNames = [])
89+ {
90+ $ callback = $ this ->memberNameCallback !== null ? $ this ->memberNameCallback : function ($ name ) {
91+ return str_replace (' ' , '_ ' , preg_replace ('/[^A-Za-z0-9]+/ ' , ' ' , $ name ));
92+ };
93+ return array_map ($ callback , $ memberNames );
94+ }
7895}
0 commit comments