/** * Generate a URL for the specified operation using the passed entity/data * * @param OperationDefinition $operation The operation specifying the route * @param mixed $entity The entity to be used to fill URL variables * @param mixed $value A value to be used to fill URL variables * * @return string|null The URL or null if the URL shouldn't be exposed. */ private function generateUrl(OperationDefinition $operation, $entity, $value = null) { $route = $operation->getRoute(); $routeVariables = $route->compile()->getVariables(); $variableValues = $route->getDefaults(); unset($variableValues['_controller']); // TODO: Allow custom route variable mappings if (is_array($value)) { $variableValues += $value; // FIXXME: Check if this is really what we want in all cases } elseif (1 === count($routeVariables)) { if (is_scalar($value)) { $variableValues[reset($routeVariables)] = $value; } elseif (is_object($value) && is_callable(array($value, 'getId'))) { // TODO Make the is_callable check more robust $variableValues[reset($routeVariables)] = $value->getId(); } elseif (is_object($entity) && is_callable(array($entity, 'getId'))) { // TODO Check if this is want in all cases $variableValues[reset($routeVariables)] = $entity->getId(); } elseif (null === $value) { return null; } } else { $accessor = PropertyAccess::createPropertyAccessor(); foreach ($routeVariables as $variable) { try { $variableValues[$variable] = $accessor->getValue($value, $variable); } catch (\Exception $e) { // do nothing, no such property exists } } } return $this->router->generate($operation->getName(), $variableValues); }