Spaces:
No application file
No application file
| namespace Mautic\ApiBundle\Serializer\Driver; | |
| use JMS\Serializer\Metadata\ClassMetadata; | |
| use JMS\Serializer\Metadata\PropertyMetadata; | |
| use Metadata\ClassMetadata as BaseClassMetadata; | |
| use Metadata\Driver\DriverInterface; | |
| class ApiMetadataDriver implements DriverInterface | |
| { | |
| private ?ClassMetadata $metadata = null; | |
| /** | |
| * @var PropertyMetadata[] | |
| */ | |
| private $properties = []; | |
| private string $groupPrefix = ''; | |
| /** | |
| * @var null | |
| */ | |
| private $defaultVersion = '1.0'; | |
| /** | |
| * @var null | |
| */ | |
| private $currentPropertyName; | |
| /** | |
| * @throws \ReflectionException | |
| */ | |
| public function loadMetadataForClass(\ReflectionClass $class): ?BaseClassMetadata | |
| { | |
| if ($class->hasMethod('loadApiMetadata')) { | |
| $this->metadata = new ClassMetadata($class->getName()); | |
| $class->getMethod('loadApiMetadata')->invoke(null, $this); | |
| $metadata = $this->metadata; | |
| $this->resetDefaults(); | |
| return $metadata; | |
| } else { | |
| return new ClassMetadata($class->getName()); | |
| } | |
| } | |
| private function resetDefaults(): void | |
| { | |
| $this->metadata = null; | |
| $this->properties = []; | |
| $this->defaultVersion = '1.0'; | |
| $this->groupPrefix = ''; | |
| } | |
| /** | |
| * Set the root (base key). | |
| * | |
| * @return $this | |
| */ | |
| public function setRoot($root) | |
| { | |
| $this->metadata->xmlRootName = $root; | |
| return $this; | |
| } | |
| /** | |
| * Set prefix for the List and Details groups. | |
| * | |
| * @return $this | |
| */ | |
| public function setGroupPrefix($name) | |
| { | |
| $this->groupPrefix = $name; | |
| return $this; | |
| } | |
| /** | |
| * Set the default version for the properties if different than 1.0. | |
| * | |
| * @return $this | |
| */ | |
| public function setDefaultVersion($version) | |
| { | |
| $this->defaultVersion = $version; | |
| return $this; | |
| } | |
| /** | |
| * Create a new property. | |
| * | |
| * @return $this | |
| */ | |
| public function createProperty($name) | |
| { | |
| if (!isset($this->properties[$name])) { | |
| $this->properties[$name] = new PropertyMetadata($this->metadata->name, $name); | |
| } | |
| $this->currentPropertyName = $name; | |
| return $this; | |
| } | |
| /** | |
| * Add property and set default version and Details group. | |
| * | |
| * @param bool $useGetter | |
| * | |
| * @return $this | |
| */ | |
| public function addProperty($name, $serializedName = null, $useGetter = false) | |
| { | |
| if (empty($name)) { | |
| return $this; | |
| } | |
| $this->createProperty($name); | |
| if ($useGetter && !$this->properties[$name]->getter) { | |
| $this->properties[$name]->getter = 'get'.ucfirst($name); | |
| } | |
| $this->properties[$name]->serializedName = $serializedName ?? $name; | |
| if (null !== $this->defaultVersion) { | |
| // Set the default version | |
| $this->setSinceVersion($this->defaultVersion); | |
| } | |
| $this->addGroup($this->groupPrefix.'Details'); | |
| return $this; | |
| } | |
| /** | |
| * Create properties. | |
| * | |
| * @param bool|false $addToListGroup | |
| * @param bool|false $useGetter | |
| * | |
| * @return $this | |
| */ | |
| public function addProperties(array $properties, $addToListGroup = false, $useGetter = false) | |
| { | |
| foreach ($properties as $prop) { | |
| if (!empty($prop)) { | |
| $serializedName = null; | |
| if (is_array($prop)) { | |
| [$prop, $serializedName] = $prop; | |
| } | |
| $this->addProperty($prop, $serializedName, $useGetter); | |
| if ($addToListGroup) { | |
| $this->inListGroup(); | |
| } | |
| } | |
| } | |
| return $this; | |
| } | |
| /** | |
| * Create properties and add to the List group. | |
| * | |
| * @return $this | |
| */ | |
| public function addListProperties(array $properties) | |
| { | |
| $this->addProperties($properties, true); | |
| return $this; | |
| } | |
| /** | |
| * @return $this | |
| */ | |
| public function setSinceVersion($version, $property = null) | |
| { | |
| if (null === $property) { | |
| $property = $this->getCurrentPropertyName(); | |
| } | |
| $this->properties[$property]->sinceVersion = $version; | |
| return $this; | |
| } | |
| /** | |
| * @return $this | |
| */ | |
| public function setUntilVersion($version, $property = null) | |
| { | |
| if (null === $property) { | |
| $property = $this->getCurrentPropertyName(); | |
| } | |
| $this->properties[$property]->untilVersion = $version; | |
| return $this; | |
| } | |
| /** | |
| * @return $this | |
| */ | |
| public function setSerializedName($name, $property = null) | |
| { | |
| if (null === $property) { | |
| $property = $this->getCurrentPropertyName(); | |
| } | |
| $this->properties[$property]->serializedName = $name; | |
| return $this; | |
| } | |
| /** | |
| * Set the groups a property belongs to. | |
| * | |
| * @return $this | |
| */ | |
| public function setGroups($groups, $property = null) | |
| { | |
| if (!is_array($groups)) { | |
| $groups = [$groups]; | |
| } | |
| if (null === $property) { | |
| $property = $this->getCurrentPropertyName(); | |
| } | |
| $this->properties[$property]->groups = $groups; | |
| return $this; | |
| } | |
| /** | |
| * Add a group the property belongs to. | |
| * | |
| * @param mixed $property | |
| * | |
| * @return $this | |
| */ | |
| public function addGroup($group, $property = null) | |
| { | |
| if (true === $property) { | |
| foreach ($this->properties as $prop => $metadata) { | |
| $this->addGroup($group, $prop); | |
| } | |
| } else { | |
| if (null === $property) { | |
| $property = $this->getCurrentPropertyName(); | |
| } | |
| $this->properties[$property]->groups[] = $group; | |
| } | |
| return $this; | |
| } | |
| /** | |
| * Add property to the List group. | |
| * | |
| * @return $this | |
| */ | |
| public function inListGroup() | |
| { | |
| $this->properties[$this->currentPropertyName]->groups[] = | |
| $this->groupPrefix.'List'; | |
| return $this; | |
| } | |
| /** | |
| * Set max depth for the property if an association. | |
| * | |
| * @return $this | |
| */ | |
| public function setMaxDepth($depth, $property = null) | |
| { | |
| if (null === $property) { | |
| $property = $this->getCurrentPropertyName(); | |
| } | |
| $this->properties[$property]->maxDepth = (int) $depth; | |
| return $this; | |
| } | |
| /** | |
| * Push the properties into ClassMetadata. | |
| */ | |
| public function build(): void | |
| { | |
| foreach ($this->properties as $prop) { | |
| $this->metadata->addPropertyMetadata($prop); | |
| } | |
| $this->currentPropertyName = null; | |
| $this->properties = []; | |
| } | |
| /** | |
| * @return string | |
| * | |
| * @throws \Exception | |
| */ | |
| protected function getCurrentPropertyName() | |
| { | |
| if (empty($this->currentPropertyName)) { | |
| throw new \Exception('Current property is not set'); | |
| } | |
| return $this->currentPropertyName; | |
| } | |
| } | |