/** * Serialize data object to id. * * @param VisitorInterface $visitor * @param object $data * @param array $type * @param Context $context * * @return int|null */ public function serializeObjectToId(VisitorInterface $visitor, $data, array $type, Context $context) { $className = $this->manager->getClass(); if ($data instanceof $className) { return $visitor->visitInteger($data->getId(), $type, $context); } return; }
public function serializeDateTime(VisitorInterface $visitor, \DateTime $date, array $type, Context $context) { if ($visitor instanceof XmlSerializationVisitor && false === $this->xmlCData) { return $visitor->visitSimpleString($date->format($this->getFormat($type)), $type, $context); } $format = $this->getFormat($type); if ('U' === $format) { return $visitor->visitInteger($date->format($format), $type, $context); } return $visitor->visitString($date->format($this->getFormat($type)), $type, $context); }
/** * Serialize identifier(s). * * Converts an object or collection of objects to an id or array of ids. * * @param VisitorInterface $visitor * @param mixed $data * @param array $type * @param Context $context * @return */ public function serializeIdentifier(VisitorInterface $visitor, $data, array $type, Context $context) { if (!is_object($data)) { return; } if ($this->isIterable($data)) { $identifiers = array(); foreach ($data as $datum) { $identifiers[] = $this->getIdentifier($datum); } return $visitor->visitArray($identifiers, $type, $context); } return $visitor->visitInteger($this->getIdentifier($data), $type, $context); }
/** * Called for each node of the graph that is being traversed. * * @param mixed $data the data depends on the direction, and type of visitor * @param null|array $type array has the format ["name" => string, "params" => array] * @param VisitorInterface $visitor * * @return mixed the return value depends on the direction, and type of visitor */ public function accept($data, array $type = null, VisitorInterface $visitor) { // If the type was not given, we infer the most specific type from the // input data in serialization mode. if (null === $type) { if (!$this->context->isSerializing()) { $msg = 'The type must be given for all properties when deserializing.'; if (null !== ($path = $this->context->getPath())) { $msg .= ' Path: ' . $path; } throw new \RuntimeException($msg); } $typeName = gettype($data); if ('object' === $typeName) { $typeName = get_class($data); } $type = array('name' => $typeName, 'params' => array()); } else { if ($this->context->isSerializing() && null === $data) { $type = array('name' => 'NULL', 'params' => array()); } } switch ($type['name']) { case 'NULL': return $visitor->visitNull($data, $type); case 'string': return $visitor->visitString($data, $type); case 'integer': return $visitor->visitInteger($data, $type); case 'boolean': return $visitor->visitBoolean($data, $type); case 'double': case 'float': return $visitor->visitDouble($data, $type); case 'array': return $visitor->visitArray($data, $type); case 'resource': $msg = 'Resources are not supported in serialized data.'; if (null !== ($path = $this->context->getPath())) { $msg .= ' Path: ' . $path; } throw new \RuntimeException($msg); default: $isSerializing = $this->context->isSerializing(); if ($isSerializing && null !== $data) { if ($this->context->isVisiting($data)) { return null; } $this->context->startVisiting($data); } // First, try whether a custom handler exists for the given type. This is done // before loading metadata because the type name might not be a class, but // could also simply be an artifical type. if (null !== ($handler = $this->handlerRegistry->getHandler($this->context->getDirection(), $type['name'], $this->context->getFormat()))) { $rs = call_user_func($handler, $visitor, $data, $type); $this->context->stopVisiting($data); return $rs; } // Trigger pre-serialization callbacks, and listeners if they exist. if ($isSerializing) { if (null !== $this->dispatcher && $this->dispatcher->hasListeners('serializer.pre_serialize', $type['name'], $this->context->getFormat())) { $this->dispatcher->dispatch('serializer.pre_serialize', $type['name'], $this->context->getFormat(), $event = new PreSerializeEvent($visitor, $data, $type)); $type = $event->getType(); } } // Load metadata, and check whether this class should be excluded. $metadata = $this->metadataFactory->getMetadataForClass($type['name']); if (null !== $this->exclusionStrategy && $this->exclusionStrategy->shouldSkipClass($metadata, $this->context)) { $this->context->stopVisiting($data); return null; } if ($isSerializing) { foreach ($metadata->preSerializeMethods as $method) { $method->invoke($data); } } $object = $data; if (!$isSerializing) { $object = $this->objectConstructor->construct($visitor, $metadata, $data, $type); } if (isset($metadata->handlerCallbacks[$this->context->getDirection()][$this->context->getFormat()])) { $rs = $object->{$metadata->handlerCallbacks[$this->context->getDirection()][$this->context->getFormat()]}($visitor, $isSerializing ? null : $data); $this->afterVisitingObject($visitor, $metadata, $object, $type); return $isSerializing ? $rs : $object; } $visitor->startVisitingObject($metadata, $object, $type); foreach ($metadata->propertyMetadata as $propertyMetadata) { if (null !== $this->exclusionStrategy && $this->exclusionStrategy->shouldSkipProperty($propertyMetadata, $this->context)) { continue; } if (!$isSerializing && $propertyMetadata->readOnly) { continue; } $visitor->visitProperty($propertyMetadata, $data); } if ($isSerializing) { $this->afterVisitingObject($visitor, $metadata, $data, $type); return $visitor->endVisitingObject($metadata, $data, $type); } $rs = $visitor->endVisitingObject($metadata, $data, $type); $this->afterVisitingObject($visitor, $metadata, $rs, $type); return $rs; } }