/** * Add the relations for the given classMetadata. Is called by the hateoas bundle * * @param $object * @param ClassMetadataInterface $classMetadata * @return array * @throws \Doctrine\ORM\Mapping\MappingException */ public function addRelations($object, ClassMetadataInterface $classMetadata) { if ($this->cache->contains('relations', $classMetadata->getName())) { return $this->cache->fetch('relations', $classMetadata->getName()); } $relations = array(); $classImplements = class_implements($classMetadata->getName()); if (in_array('uebb\\HateoasBundle\\Entity\\ResourceInterface', $classImplements)) { $selfRoute = $this->routeResolver->resolveRouteName($classMetadata->getName(), 'getAction'); if ($selfRoute) { $relations[] = new Hateoas\Relation('self', new Hateoas\Route($selfRoute, array('id' => 'expr(object.getId())'), false), null, array(), new Hateoas\Exclusion(null, null, null, null, 'expr(object.getId() === NULL)')); } if (is_subclass_of($classMetadata->getName(), 'uebb\\HateoasBundle\\Entity\\File')) { $downloadRoute = $this->routeResolver->resolveRouteName($classMetadata->getName(), 'getDownloadAction'); $arguments = array('id' => 'expr(object.getId())'); if (in_array('uebb\\HateoasBundle\\Entity\\ImageInterface', $classImplements)) { foreach (self::$IMAGE_ARGUMENTS as $argument) { $arguments[$argument] = '{' . $argument . '}'; } } $relations[] = new Hateoas\Relation('download', new Hateoas\Route($downloadRoute, $arguments, false), null, array(), new Hateoas\Exclusion(null, null, null, null, 'expr(object.getId() === NULL)')); } /** @var ClassMetadata $metadata */ $metadata = $this->entityManager->getClassMetadata($classMetadata->getName()); $notExistingRoutes = array(); foreach ($metadata->getAssociationNames() as $associationName) { $mapping = $metadata->getAssociationMapping($associationName); $routeName = null; if ($metadata->isSingleValuedAssociation($associationName)) { $routeName = $this->routeResolver->resolveRouteName($mapping['targetEntity'], 'getAction'); $args = array('id' => 'expr(object.get' . ucfirst($associationName) . '().getId())'); $exclusion = new Hateoas\Exclusion(null, null, null, null, 'expr(null === object.get' . ucfirst($associationName) . '())'); } else { $routeName = $this->routeResolver->resolveRouteName($classMetadata->getName(), 'get' . ucfirst($associationName) . 'Action'); $args = array('id' => 'expr(object.getId())'); if (!$routeName) { $routeName = $this->routeResolver->resolveRouteName($classMetadata->getName(), 'getLinkcollection', array('rel' => $associationName)); $args['rel'] = $associationName; } $exclusion = null; } if ($routeName) { if ($mapping['fetch'] === ClassMetadataInfo::FETCH_EAGER) { $embedded = 'expr(object.get' . ucfirst($associationName) . '())'; } else { $embedded = null; } $relations[] = new Hateoas\Relation($associationName, new Hateoas\Route($routeName, $args, false), $embedded, array(), $exclusion); } } } $this->cache->save('relations', $classMetadata->getName(), $relations); return $relations; }
/** * @param String $resourceClass * @param String $action * @return mixed * @throws \Doctrine\Common\Persistence\Mapping\MappingException * @throws \Exception */ public function resolveRouteName($resourceClass, $action, $args = array()) { $key = serialize(array($resourceClass, $action, $args)); if ($this->cache->contains('routes', $key)) { return $this->cache->fetch('routes', $key); } foreach ($this->router->getRouteCollection()->all() as $name => $route) { $defaults = $route->getDefaults(); $parts = explode('::', $defaults['_controller']); if (count($parts) === 2) { $reflection = new \ReflectionClass($parts[0]); $defaultProperties = $reflection->getdefaultProperties(); if (is_subclass_of($parts[0], '\\uebb\\HateoasBundle\\Controller\\HateoasController') && $parts[1] === $action && $this->entityManager->getMetadataFactory()->getMetadataFor($defaultProperties['entityName'])->getName() === $resourceClass) { if ($args === array_intersect_key($defaults, $args)) { $this->cache->save('routes', $key, $name); return $name; } } } } $this->cache->save('routes', $key, null); return null; }