88use Swaggest \JsonSchema \JsonSchema ;
99use Swaggest \JsonSchema \Schema ;
1010use Swaggest \JsonSchema \SchemaContract ;
11+ use Swaggest \JsonSchema \SchemaExporter ;
1112use Swaggest \PhpCodeBuilder \Exception ;
1213use Swaggest \PhpCodeBuilder \PhpAnyType ;
1314use Swaggest \PhpCodeBuilder \PhpClass ;
@@ -148,12 +149,19 @@ private function makeClass($schema, $path)
148149
149150 if ($ schema ->properties ) {
150151 $ phpNames = array ();
152+ /**
153+ * @var string $name
154+ * @var Schema $property
155+ */
151156 foreach ($ schema ->properties as $ name => $ property ) {
152- $ i = '' ;
153- do {
154- $ propertyName = PhpCode::makePhpName ($ name . $ i );
155- $ i .= 'a ' ;
156- } while (isset ($ phpNames [$ propertyName ]));
157+ $ propertyName = PhpCode::makePhpName ($ name );
158+
159+ $ i = 2 ;
160+ $ basePropertyName = $ propertyName ;
161+ while (isset ($ phpNames [$ propertyName ])) {
162+ $ propertyName = $ basePropertyName . $ i ;
163+ $ i ++;
164+ }
157165 $ phpNames [$ propertyName ] = true ;
158166
159167 $ schemaBuilder = new SchemaBuilder ($ property , '$properties-> ' . $ propertyName , $ path . '-> ' . $ name , $ this );
@@ -163,9 +171,15 @@ private function makeClass($schema, $path)
163171 if ($ this ->makeEnumConstants ) {
164172 $ schemaBuilder ->setSaveEnumConstInClass ($ class );
165173 }
166- $ phpProperty = new PhpClassProperty ($ propertyName , $ this ->getType ($ property , $ path . '-> ' . $ name ));
174+ $ propertyType = $ this ->getType ($ property , $ path . '-> ' . $ name );
175+ $ phpProperty = new PhpClassProperty ($ propertyName , $ propertyType );
167176 $ phpProperty ->addMeta ($ property , self ::SCHEMA );
168177 $ phpProperty ->addMeta ($ name , self ::PROPERTY_NAME );
178+
179+ if ($ this ->schemaIsNullable ($ property )) {
180+ $ phpProperty ->setIsMagical (true );
181+ }
182+
169183 if ($ property ->description ) {
170184 $ phpProperty ->setDescription ($ property ->description );
171185 }
@@ -261,6 +275,73 @@ public static function getSchemaMeta(AbstractTemplate $template)
261275 {
262276 return $ template ->getMeta (self ::SCHEMA );
263277 }
278+
279+ /**
280+ * Returns true if null is allowed by schema.
281+ *
282+ * @param Schema $property
283+ * @return bool
284+ */
285+ private function schemaIsNullable ($ property )
286+ {
287+ if (!empty ($ property ->enum ) && !in_array (null , $ property ->enum )) {
288+ return false ;
289+ }
290+
291+ if ($ property ->const !== null ) {
292+ return false ;
293+ }
294+
295+ if (!empty ($ property ->anyOf )) {
296+ $ nullable = false ;
297+ foreach ($ property ->anyOf as $ item ) {
298+ if ($ item instanceof Schema) {
299+ if ($ this ->schemaIsNullable ($ item )) {
300+ $ nullable = true ;
301+ break ;
302+ }
303+ }
304+ }
305+ if (!$ nullable ) {
306+ return false ;
307+ }
308+ }
309+
310+ if (!empty ($ property ->oneOf )) {
311+ $ nullable = false ;
312+ foreach ($ property ->oneOf as $ item ) {
313+ if ($ item instanceof Schema) {
314+ if ($ this ->schemaIsNullable ($ item )) {
315+ $ nullable = true ;
316+ break ;
317+ }
318+ }
319+ }
320+ if (!$ nullable ) {
321+ return false ;
322+ }
323+ }
324+
325+ if (!empty ($ property ->allOf )) {
326+ foreach ($ property ->allOf as $ item ) {
327+ if ($ item instanceof Schema) {
328+ if (!$ this ->schemaIsNullable ($ item )) {
329+ return false ;
330+ }
331+ }
332+ }
333+ }
334+
335+ if (
336+ $ property ->type === null
337+ || $ property ->type === Schema::NULL
338+ || (is_array ($ property ->type ) && in_array (Schema::NULL , $ property ->type ))
339+ ) {
340+ return true ;
341+ }
342+
343+ return false ;
344+ }
264345}
265346
266347
0 commit comments