Skip to content
This repository has been archived by the owner on Dec 13, 2022. It is now read-only.

Commit

Permalink
fix(api): fix serializer constructor call (#10088)
Browse files Browse the repository at this point in the history
  • Loading branch information
callapa authored and tuntoja committed Oct 7, 2021
1 parent 1ac9089 commit a71e851
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

/*
* Copyright 2005 - 2021 Centreon (https://www.centreon.com/)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* For more information : contact@centreon.com
*
*/
declare(strict_types=1);

namespace Centreon\Infrastructure\Serializer\Exception;

/**
* This class is designed to contain all exceptions concerning deserialization.
*
* @package Centreon\Infrastructure\Serializer\Exception
*/
class SerializerException extends \Exception
{
/**
* @param string $classname
* @param \Throwable $ex
* @return self
*/
public static function notEnoughConstructorArguments(string $classname, \Throwable $ex): self
{
return new self(sprintf(_('There are not enough arguments to build the object %s'), $classname), 0, $ex);
}

/**
* @param string $className
* @return self
*/
public static function classNotFound(string $className): self
{
return new self(sprintf(_('Class %s not found'), $className));
}
}
36 changes: 33 additions & 3 deletions src/Centreon/Infrastructure/Serializer/ObjectConstructor.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@
* limitations under the License.
*
* For more information : contact@centreon.com
*Controller
*
*/
declare(strict_types=1);

namespace Centreon\Infrastructure\Serializer;

use Centreon\Infrastructure\Serializer\Exception\SerializerException;
use JMS\Serializer\Construction\ObjectConstructorInterface;
use JMS\Serializer\DeserializationContext;
use JMS\Serializer\Metadata\ClassMetadata;
Expand All @@ -35,7 +36,11 @@
class ObjectConstructor implements ObjectConstructorInterface
{
/**
* @inheritDoc
* {@inheritDoc}
* @param array<string, mixed> $type
* @throws SerializerException
* @throws \ReflectionException
* @throws \Throwable
*/
public function construct(
DeserializationVisitorInterface $visitor,
Expand All @@ -45,6 +50,31 @@ public function construct(
DeserializationContext $context
): ?object {
$className = $metadata->name;
return new $className();
if (!class_exists($className)) {
throw SerializerException::classNotFound($className);
}
$reflection = new \ReflectionClass($className);
$constructor = $reflection->getConstructor();
if ($constructor !== null && $constructor->getNumberOfParameters() > 0) {
$parameters = $constructor->getParameters();
$constructorParameters = [];
foreach ($parameters as $parameter) {
if (array_key_exists($parameter->getName(), $data)) {
$constructorParameters[$parameter->getPosition()] = $data[$parameter->getName()];
} elseif ($parameter->isOptional() === true) {
$constructorParameters[$parameter->getPosition()] = $parameter->getDefaultValue();
}
}
try {
return $reflection->newInstanceArgs($constructorParameters);
} catch (\Throwable $ex) {
if ($ex instanceof \ArgumentCountError) {
throw SerializerException::notEnoughConstructorArguments($className, $ex);
}
throw $ex;
}
} else {
return new $className();
}
}
}

0 comments on commit a71e851

Please sign in to comment.