/** * (@inheritDoc} */ public function createNormalizationStatement(Context $context, Expr $input) { $output = new Expr\Variable($context->getUniqueVariableName('value')); $statements = [new Expr\Assign($output, $input)]; foreach ($this->getTypes() as $type) { list($typeStatements, $typeOutput) = $type->createNormalizationStatement($context, $input); $statements[] = new Stmt\If_($type->createNormalizationConditionStatement($input), ['stmts' => array_merge($typeStatements, [new Expr\Assign($output, $typeOutput)])]); } return [$statements, $output]; }
/** * (@inheritDoc} */ public function createNormalizationStatement(Context $context, Expr $input) { $valuesVar = new Expr\Variable($context->getUniqueVariableName('values')); $statements = [new Expr\Assign($valuesVar, $this->createNormalizationArrayValueStatement())]; $loopValueVar = new Expr\Variable($context->getUniqueVariableName('value')); $loopKeyVar = $this->createLoopKeyStatement($context); list($subStatements, $outputExpr) = $this->itemType->createNormalizationStatement($context, $loopValueVar); $loopStatements = array_merge($subStatements, [new Expr\Assign($this->createNormalizationLoopOutputAssignement($valuesVar, $loopKeyVar), $outputExpr)]); $statements[] = new Stmt\Foreach_($input, $loopValueVar, ['keyVar' => $loopKeyVar, 'stmts' => $loopStatements]); return [$statements, $valuesVar]; }
/** * Create the denormalization method * * @param $modelFqdn * @param Context $context * @param $properties * * @return Stmt\ClassMethod */ protected function createDenormalizeMethod($modelFqdn, Context $context, $properties) { $context->refreshScope(); $objectVariable = new Expr\Variable('object'); $statements = [new Stmt\If_(new Expr\Empty_(new Expr\Variable('data')), ['stmts' => [new Stmt\Return_(new Expr\ConstFetch(new Name("null")))]]), new Stmt\If_(new Expr\Isset_([new Expr\PropertyFetch(new Expr\Variable('data'), "{'\$ref'}")]), ['stmts' => [new Stmt\Return_(new Expr\New_(new Name('Reference'), [new Expr\PropertyFetch(new Expr\Variable('data'), "{'\$ref'}"), new Expr\Ternary(new Expr\ArrayDimFetch(new Expr\Variable('context'), new Scalar\String_('rootSchema')), null, new Expr\ConstFetch(new Name("null")))]))]]), new Expr\Assign($objectVariable, new Expr\New_(new Name("\\" . $modelFqdn))), new Stmt\If_(new Expr\BooleanNot(new Expr\Isset_([new Expr\ArrayDimFetch(new Expr\Variable('context'), new Scalar\String_('rootSchema'))])), ['stmts' => [new Expr\Assign(new Expr\ArrayDimFetch(new Expr\Variable('context'), new Scalar\String_('rootSchema')), $objectVariable)]])]; foreach ($properties as $property) { $propertyVar = new Expr\PropertyFetch(new Expr\Variable('data'), sprintf("{'%s'}", $property->getName())); list($denormalizationStatements, $outputVar) = $property->getType()->createDenormalizationStatement($context, $propertyVar); $statements[] = new Stmt\If_(new Expr\FuncCall(new Name('property_exists'), [new Arg(new Expr\Variable('data')), new Arg(new Scalar\String_($property->getName()))]), ['stmts' => array_merge($denormalizationStatements, [new Expr\MethodCall($objectVariable, $this->getNaming()->getPrefixedMethodName('set', $property->getName()), [$outputVar])])]); } $statements[] = new Stmt\Return_($objectVariable); return new Stmt\ClassMethod('denormalize', ['type' => Stmt\Class_::MODIFIER_PUBLIC, 'params' => [new Param('data'), new Param('class'), new Param('format', new Expr\ConstFetch(new Name("null"))), new Param('context', new Expr\Array_(), 'array')], 'stmts' => $statements]); }
/** * Generate a model given a schema * * @param mixed $schema Schema to generate from * @param string $className Class to generate * @param Context $context Context for generation * * @return File[] */ public function generate($schema, $className, Context $context) { $files = []; foreach ($context->getObjectClassMap() as $class) { $properties = []; $methods = []; foreach ($class->getProperties() as $property) { $properties[] = $this->createProperty($property->getName(), $property->getType()); $methods[] = $this->createGetter($property->getName(), $property->getType()); $methods[] = $this->createSetter($property->getName(), $property->getType()); } $model = $this->createModel($class->getName(), $properties, $methods); $namespace = new Stmt\Namespace_(new Name($context->getNamespace() . "\\Model"), [$model]); $files[] = new File($context->getDirectory() . '/Model/' . $class->getName() . '.php', $namespace, self::FILE_TYPE_MODEL); } return $files; }
/** * Generate a set of files given a schema * * @param mixed $schema Schema to generate from * @param string $className Class to generate * @param Context $context Context for generation * * @return File[] */ public function generate($schema, $className, Context $context) { $files = []; $classes = []; foreach ($context->getObjectClassMap() as $class) { $methods = []; $modelFqdn = $context->getNamespace() . "\\Model\\" . $class->getName(); $methods[] = $this->createSupportsDenormalizationMethod($modelFqdn); $methods[] = $this->createSupportsNormalizationMethod($modelFqdn); $methods[] = $this->createDenormalizeMethod($modelFqdn, $context, $class->getProperties()); $methods[] = $this->createNormalizeMethod($modelFqdn, $context, $class->getProperties()); $normalizerClass = $this->createNormalizerClass($class->getName() . 'Normalizer', $methods); $classes[] = $normalizerClass->name; $namespace = new Stmt\Namespace_(new Name($context->getNamespace() . "\\Normalizer"), [new Stmt\Use_([new Stmt\UseUse(new Name('Joli\\Jane\\Runtime\\Reference'))]), new Stmt\Use_([new Stmt\UseUse(new Name('Symfony\\Component\\Serializer\\Normalizer\\DenormalizerInterface'))]), new Stmt\Use_([new Stmt\UseUse(new Name('Symfony\\Component\\Serializer\\Normalizer\\NormalizerInterface'))]), new Stmt\Use_([new Stmt\UseUse(new Name('Symfony\\Component\\Serializer\\Normalizer\\SerializerAwareNormalizer'))]), $normalizerClass]); $files[] = new File($context->getDirectory() . '/Normalizer/' . $class->getName() . 'Normalizer.php', $namespace, self::FILE_TYPE_NORMALIZER); } $files[] = new File($context->getDirectory() . '/Normalizer/NormalizerFactory.php', new Stmt\Namespace_(new Name($context->getNamespace() . "\\Normalizer"), [$this->createNormalizerFactoryClass($classes)]), self::FILE_TYPE_NORMALIZER); return $files; }
/** * Create the normalization method. * * @param $modelFqdn * @param Context $context * @param $properties * * @return Stmt\ClassMethod */ protected function createNormalizeMethod($modelFqdn, Context $context, $properties) { $context->refreshScope(); $dataVariable = new Expr\Variable('data'); $statements = [new Expr\Assign($dataVariable, new Expr\New_(new Name('\\stdClass')))]; /** @var Property $property */ foreach ($properties as $property) { $propertyVar = new Expr\MethodCall(new Expr\Variable('object'), $this->getNaming()->getPrefixedMethodName('get', $property->getName())); list($normalizationStatements, $outputVar) = $property->getType()->createNormalizationStatement($context, $propertyVar); $normalizationStatements[] = new Expr\Assign(new Expr\PropertyFetch($dataVariable, sprintf("{'%s'}", $property->getName())), $outputVar); if ($property->isNullable()) { $statements = array_merge($statements, $normalizationStatements); continue; } $statements[] = new Stmt\If_(new Expr\BinaryOp\NotIdentical(new Expr\ConstFetch(new Name('null')), $propertyVar), ['stmts' => $normalizationStatements]); } $statements[] = new Stmt\Return_($dataVariable); return new Stmt\ClassMethod('normalize', ['type' => Stmt\Class_::MODIFIER_PUBLIC, 'params' => [new Param('object'), new Param('format', new Expr\ConstFetch(new Name('null'))), new Param('context', new Expr\Array_(), 'array')], 'stmts' => $statements]); }
/** * @param $status * @param $schema * @param Context $context * * @return null|Stmt\If_ */ protected function createResponseDenormalizationStatement($status, $schema, Context $context) { $resolvedSchema = null; $array = false; if ($schema instanceof Reference) { $resolvedSchema = $this->getResolver()->resolve($schema); } if ($schema instanceof Schema && $schema->getType() == "array" && $schema->getItems() instanceof Reference) { $resolvedSchema = $this->getResolver()->resolve($schema->getItems()); $array = true; } if ($resolvedSchema === null) { return [null, null]; } $class = $context->getObjectClassMap()[spl_object_hash($resolvedSchema)]; $class = $context->getNamespace() . "\\Model\\" . $class->getName(); if ($array) { $class .= "[]"; } return ["\\" . $class, new Stmt\If_(new Expr\BinaryOp\Equal(new Scalar\String_($status), new Expr\MethodCall(new Expr\Variable('response'), 'getStatusCode')), ['stmts' => [new Stmt\Return_(new Expr\MethodCall(new Expr\PropertyFetch(new Expr\Variable('this'), 'serializer'), 'deserialize', [new Arg(new Expr\Cast\String_(new Expr\MethodCall(new Expr\Variable('response'), 'getBody'))), new Arg(new Scalar\String_($class)), new Arg(new Scalar\String_('json'))]))]])]; }
/** * @param BodyParameter $parameter * @param Context $context * * @return array */ protected function getClass(BodyParameter $parameter, Context $context) { $resolvedSchema = null; $array = false; $schema = $parameter->getSchema(); if ($schema instanceof Reference) { $resolvedSchema = $this->resolver->resolve($schema); } if ($schema instanceof Schema && $schema->getType() == "array" && $schema->getItems() instanceof Reference) { $resolvedSchema = $this->resolver->resolve($schema->getItems()); $array = true; } if ($resolvedSchema === null) { return [$schema->getType(), null]; } $class = $context->getObjectClassMap()[spl_object_hash($resolvedSchema)]; $class = "\\" . $context->getNamespace() . "\\Model\\" . $class->getName(); if ($array) { $class .= "[]"; } return [$class, $array]; }
/** * {@inheritDoc} */ protected function createLoopKeyStatement(Context $context) { return new Expr\Variable($context->getUniqueVariableName('key')); }
/** * (@inheritDoc} */ protected function createDenormalizationValueStatement(Context $context, Expr $input) { $fqdn = $context->getNamespace() . '\\Model\\' . $this->className; return new Expr\MethodCall(new Expr\PropertyFetch(new Expr\Variable('this'), 'serializer'), 'deserialize', [new Arg($input), new Arg(new Scalar\String_($fqdn)), new Arg(new Scalar\String_('raw')), new Arg(new Expr\Variable('context'))]); }