diff --git a/src/main/app/API/Crud.php b/src/main/app/API/Crud.php index 76b93876ebe..ae425c3bd04 100644 --- a/src/main/app/API/Crud.php +++ b/src/main/app/API/Crud.php @@ -72,13 +72,22 @@ public function __construct( * * @return object|null */ - public function get(string $class, $id) + public function get(string $class, $id, string $idProp = 'id') { - if (!is_numeric($id) && property_exists($class, 'uuid')) { - return $this->om->getRepository($class)->findOneBy(['uuid' => $id]); + if ('id' === $idProp) { + if (!is_numeric($id) && property_exists($class, 'uuid')) { + return $this->om->getRepository($class)->findOneBy(['uuid' => $id]); + } + + return $this->om->getRepository($class)->findOneBy(['id' => $id]); + } + + $identifiers = $this->schema->getIdentifiers($class); + if (!in_array($idProp, $identifiers)) { + throw new \LogicException(sprintf('You can only get entities with an identifier property (identifiers: %s).', implode(', ', $identifiers))); } - return $this->om->getRepository($class)->findOneBy(['id' => $id]); + return $this->om->getRepository($class)->findOneBy([$idProp => $id]); } public function find(string $class, $data) diff --git a/src/main/app/Controller/AbstractCrudController.php b/src/main/app/Controller/AbstractCrudController.php index d19cc8465e4..6cb2482f7e8 100644 --- a/src/main/app/Controller/AbstractCrudController.php +++ b/src/main/app/Controller/AbstractCrudController.php @@ -99,7 +99,8 @@ public function findAction(Request $request, $class) * @ApiDoc( * description="Finds an object class $class.", * parameters={ - * {"name": "id", "type": {"string", "integer"}, "description": "The object id or uuid"} + * {"name": "field", "type": "string", "description": "The name of the identifier we want to use (eg. id, slug)"}, + * {"name": "id", "type": {"string", "integer"}, "description": "The object identifier value"} * }, * response={"$object"} * ) @@ -107,22 +108,18 @@ public function findAction(Request $request, $class) * @param string|int $id * @param string $class */ - public function getAction(Request $request, $id, $class): JsonResponse + public function getAction(string $field, $id, $class): JsonResponse { - $query = $request->query->all(); - $object = $this->crud->get($class, $id); + $options = static::getOptions(); - $options = $this->options['get']; - if (isset($query['options'])) { - $options = $query['options']; - } + $object = $this->crud->get($class, $id, $field); if (!$object) { throw new NotFoundHttpException(sprintf('No object found for id %s of class %s', $id.'', $class)); } return new JsonResponse( - $this->serializer->serialize($object, $options ?? []) + $this->serializer->serialize($object, $options['get'] ?? []) ); } diff --git a/src/main/app/Routing/ApiLoader.php b/src/main/app/Routing/ApiLoader.php index 12203d2c84f..99fa2c85914 100644 --- a/src/main/app/Routing/ApiLoader.php +++ b/src/main/app/Routing/ApiLoader.php @@ -13,16 +13,17 @@ class ApiLoader extends Loader { + // Route format : [path, method, defaults] const DEFAULT_MAP = [ - 'create' => ['', 'POST'], - 'deleteBulk' => ['', 'DELETE'], - 'list' => ['', 'GET'], - 'csv' => ['/csv', 'GET'], - 'find' => ['/find', 'GET'], - 'copyBulk' => ['/copy', 'GET'], - 'update' => ['/{id}', 'PUT'], - 'get' => ['/{id}', 'GET'], - 'exist' => ['/exist/{field}/{value}', 'GET'], + 'create' => ['', 'POST'], + 'deleteBulk' => ['', 'DELETE'], + 'list' => ['', 'GET'], + 'csv' => ['/csv', 'GET'], + 'find' => ['/find', 'GET'], + 'copyBulk' => ['/copy', 'GET'], + 'update' => ['/{id}', 'PUT'], + 'get' => ['/{field}/{id}', 'GET', ['field' => 'id']], + 'exist' => ['/exist/{field}/{value}', 'GET'], ]; /** @var bool */ @@ -151,6 +152,9 @@ private function loadFromPath($path, RouteCollection $routes) $route = new ApiRoute($pattern, $routeDefaults, []); $route->setAction($name); $route->setMethods([$options[1]]); + if (isset($options[2])) { + $route->addDefaults($options[2]); + } $requirements = $refClass->newInstanceWithoutConstructor()->getRequirements(); if (isset($requirements[$name])) { diff --git a/src/main/community/Resources/modules/tools/community/user/store/actions.js b/src/main/community/Resources/modules/tools/community/user/store/actions.js index f32f7966c83..93557dc65d9 100644 --- a/src/main/community/Resources/modules/tools/community/user/store/actions.js +++ b/src/main/community/Resources/modules/tools/community/user/store/actions.js @@ -38,7 +38,7 @@ actions.open = (username, reload = false) => (dispatch, getState) => { return dispatch({ [API_REQUEST]: { - url: url(['apiv2_user_find'], {filters: {username: username}}), + url: ['apiv2_user_get', {field: 'username', id: username}], silent: true, success: (response, dispatch) => dispatch(formActions.resetForm(selectors.FORM_NAME, response, false)) } diff --git a/src/main/core/Controller/WorkspaceController.php b/src/main/core/Controller/WorkspaceController.php index d7e5a325d12..e0f1fd00297 100644 --- a/src/main/core/Controller/WorkspaceController.php +++ b/src/main/core/Controller/WorkspaceController.php @@ -173,11 +173,7 @@ public function openAction(string $slug, ?User $user = null): JsonResponse * Opens a tool. * * @Route("/{id}/tool/{toolName}", name="claro_workspace_open_tool") - * @EXT\ParamConverter( - * "workspace", - * class="Claroline\CoreBundle\Entity\Workspace\Workspace", - * options={"mapping": {"id": "uuid"}} - * ) + * @EXT\ParamConverter("workspace", class="Claroline\CoreBundle\Entity\Workspace\Workspace", options={"mapping": {"id": "uuid"}}) */ public function openToolAction(Workspace $workspace, string $toolName): JsonResponse { @@ -220,11 +216,7 @@ public function openToolAction(Workspace $workspace, string $toolName): JsonResp * Submit access code. * * @Route("/unlock/{id}", name="claro_workspace_unlock", methods={"POST"}) - * @EXT\ParamConverter( - * "workspace", - * class="Claroline\CoreBundle\Entity\Workspace\Workspace", - * options={"mapping": {"id": "uuid"}} - * ) + * @EXT\ParamConverter("workspace", class="Claroline\CoreBundle\Entity\Workspace\Workspace", options={"mapping": {"id": "uuid"}}) */ public function unlockAction(Workspace $workspace, Request $request): JsonResponse { diff --git a/src/plugin/claco-form/Controller/API/EntryController.php b/src/plugin/claco-form/Controller/API/EntryController.php index a860673f07d..63207860abe 100644 --- a/src/plugin/claco-form/Controller/API/EntryController.php +++ b/src/plugin/claco-form/Controller/API/EntryController.php @@ -57,10 +57,10 @@ public function getName(): string return 'clacoformentry'; } - public function getAction(Request $request, $id, $class): JsonResponse + public function getAction(string $field, $id, $class): JsonResponse { /** @var Entry $entry */ - $entry = $this->crud->get($class, $id); + $entry = $this->crud->get($class, $id, $field); if (!$entry) { throw new NotFoundHttpException('Entry cannot be found'); } diff --git a/src/plugin/message/Controller/MessageController.php b/src/plugin/message/Controller/MessageController.php index 85afc0581bf..784ff2a58d6 100644 --- a/src/plugin/message/Controller/MessageController.php +++ b/src/plugin/message/Controller/MessageController.php @@ -277,23 +277,19 @@ public function getRootAction($id): JsonResponse return new JsonResponse($this->serializer->serialize($root, [Options::IS_RECURSIVE])); } - public function getAction(Request $request, $id, $class): JsonResponse + public function getAction(string $field, $id, $class): JsonResponse { $currentUser = $this->tokenStorage->getToken()->getUser(); - $query = $request->query->all(); $object = $this->crud->get($class, $id); $um = $this->om->getRepository(UserMessage::class)->findOneBy(['message' => $object, 'user' => $currentUser]); $this->crud->replace($um, 'isRead', true); - $options = $this->options['get']; - if (isset($query['options'])) { - $options = $query['options']; - } + $options = static::getOptions(); if ($object) { return new JsonResponse( - $this->serializer->serialize($object, $options) + $this->serializer->serialize($object, $options['get'] ?? []) ); }