* * 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. */ namespace JMS\Serializer\Construction; use Doctrine\Common\Persistence\ManagerRegistry; use JMS\Serializer\VisitorInterface; use JMS\Serializer\Metadata\ClassMetadata; /** * Doctrine object constructor for new (or existing) objects during deserialization. */ class DoctrineObjectConstructor implements ObjectConstructorInterface { private $managerRegistry; private $fallbackConstructor; /** * Constructor. * * @param ManagerRegistry $managerRegistry Manager registry * @param ObjectConstructorInterface $fallbackConstructor Fallback object constructor */ public function __construct(ManagerRegistry $managerRegistry, ObjectConstructorInterface $fallbackConstructor) { $this->managerRegistry = $managerRegistry; $this->fallbackConstructor = $fallbackConstructor; } /** * {@inheritdoc} */ public function construct(VisitorInterface $visitor, ClassMetadata $metadata, $data, array $type) { // Locate possible ObjectManager $objectManager = $this->managerRegistry->getManagerForClass($metadata->name); if (!$objectManager) { // No ObjectManager found, proceed with normal deserialization return $this->fallbackConstructor->construct($visitor, $metadata, $data, $type); } // Locate possible ClassMetadata $classMetadataFactory = $objectManager->getMetadataFactory(); if ($classMetadataFactory->isTransient($metadata->name)) { // No ClassMetadata found, proceed with normal deserialization return $this->fallbackConstructor->construct($visitor, $metadata, $data, $type); } // Managed entity, check for proxy load if (!is_array($data)) { // Single identifier, load proxy return $objectManager->getReference($metadata->name, $data); } // Fallback to default constructor if missing identifier(s) $classMetadata = $objectManager->getClassMetadata($metadata->name); $identifierList = array(); foreach ($classMetadata->getIdentifierFieldNames() as $name) { if ( ! isset($data[$name])) { return $this->fallbackConstructor->construct($visitor, $metadata, $data, $type); } $identifierList[$name] = $data[$name]; } // Entity update, load it from database $object = $objectManager->find($metadata->name, $identifierList); $objectManager->initializeObject($object); return $object; } }