├── .gitignore ├── .php_cs ├── Readme.md ├── composer.json ├── .php_cs.cache └── src └── UuidParamConverter.php /.gitignore: -------------------------------------------------------------------------------- 1 | phpunit.xml 2 | vendor 3 | composer.lock -------------------------------------------------------------------------------- /.php_cs: -------------------------------------------------------------------------------- 1 | in(__DIR__.'/src') 5 | ; 6 | 7 | return PhpCsFixer\Config::create() 8 | ->setRules([ 9 | '@Symfony' => true, 10 | 'array_syntax' => ['syntax' => 'short'], 11 | ]) 12 | ->setFinder($finder) 13 | ; -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # UUID Param Converter 2 | 3 | An excellent ParamConverter that works with SensioLabsExtraBundle. 4 | 5 | It converter parameters of the following pattern: 6 | - `name`_uuid 7 | - `name`Uuid 8 | - uuid 9 | 10 | ## Install 11 | 12 | ``` 13 | composer require happyr/uuid-param-converter 14 | ``` 15 | 16 | ```yaml 17 | # app/config/happyr_param_converter.yml 18 | services: 19 | Happyr\UuidParamConverter: 20 | arguments: ['@doctrine.registry'] 21 | tags: 22 | - { name: request.param_converter, priority: 5, converter: uuid_converter } 23 | ``` -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "happyr/uuid-param-converter", 3 | "type": "library", 4 | "description": "A simple param converter that handles UUID", 5 | "license": "MIT", 6 | "authors": [ 7 | { 8 | "name": "Tobias Nyholm", 9 | "email": "tobias.nyholm@gmail.com" 10 | } 11 | ], 12 | "require": { 13 | "php": "^7.2", 14 | "doctrine/persistence": "^1.1 || ^2.0", 15 | "sensio/framework-extra-bundle": "^5.4", 16 | "symfony/http-kernel": "^4.3 || ^5.0" 17 | }, 18 | "autoload": { 19 | "psr-4": { "Happyr\\": "src/" } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /.php_cs.cache: -------------------------------------------------------------------------------- 1 | {"php":"7.4.5","version":"2.16.1:v2.16.1#c8afb599858876e95e8ebfcd97812d383fa23f02","indent":" ","lineEnding":"\n","rules":{"array_syntax":{"syntax":"short"},"binary_operator_spaces":true,"blank_line_after_opening_tag":true,"blank_line_before_statement":{"statements":["return"]},"braces":{"allow_single_line_closure":true},"cast_spaces":true,"class_attributes_separation":{"elements":["method"]},"class_definition":{"single_line":true},"concat_space":true,"declare_equal_normalize":true,"function_typehint_space":true,"include":true,"increment_style":true,"lowercase_cast":true,"lowercase_static_reference":true,"magic_constant_casing":true,"magic_method_casing":true,"method_argument_space":true,"native_function_casing":true,"native_function_type_declaration_casing":true,"new_with_braces":true,"no_blank_lines_after_class_opening":true,"no_blank_lines_after_phpdoc":true,"no_empty_comment":true,"no_empty_phpdoc":true,"no_empty_statement":true,"no_extra_blank_lines":{"tokens":["curly_brace_block","extra","parenthesis_brace_block","square_brace_block","throw","use"]},"no_leading_import_slash":true,"no_leading_namespace_whitespace":true,"no_mixed_echo_print":true,"no_multiline_whitespace_around_double_arrow":true,"no_short_bool_cast":true,"no_singleline_whitespace_before_semicolons":true,"no_spaces_around_offset":true,"no_superfluous_phpdoc_tags":{"allow_mixed":true,"allow_unused_params":true},"no_trailing_comma_in_list_call":true,"no_trailing_comma_in_singleline_array":true,"no_unneeded_control_parentheses":true,"no_unneeded_curly_braces":true,"no_unneeded_final_method":true,"no_unused_imports":true,"no_whitespace_before_comma_in_array":true,"no_whitespace_in_blank_line":true,"normalize_index_brace":true,"object_operator_without_whitespace":true,"ordered_imports":true,"php_unit_fqcn_annotation":true,"phpdoc_align":{"tags":["method","param","property","return","throws","type","var"]},"phpdoc_annotation_without_dot":true,"phpdoc_indent":true,"phpdoc_inline_tag":true,"phpdoc_no_access":true,"phpdoc_no_alias_tag":true,"phpdoc_no_package":true,"phpdoc_no_useless_inheritdoc":true,"phpdoc_return_self_reference":true,"phpdoc_scalar":true,"phpdoc_separation":true,"phpdoc_single_line_var_spacing":true,"phpdoc_summary":true,"phpdoc_to_comment":true,"phpdoc_trim":true,"phpdoc_trim_consecutive_blank_line_separation":true,"phpdoc_types":true,"phpdoc_types_order":{"null_adjustment":"always_last","sort_algorithm":"none"},"phpdoc_var_without_name":true,"return_type_declaration":true,"semicolon_after_instruction":true,"short_scalar_cast":true,"single_blank_line_before_namespace":true,"single_class_element_per_statement":true,"single_line_comment_style":{"comment_types":["hash"]},"single_line_throw":true,"single_quote":true,"single_trait_insert_per_statement":true,"space_after_semicolon":{"remove_in_empty_for_expressions":true},"standardize_increment":true,"standardize_not_equals":true,"ternary_operator_spaces":true,"trailing_comma_in_multiline_array":true,"trim_array_spaces":true,"unary_operator_spaces":true,"whitespace_after_comma_in_array":true,"yoda_style":true,"blank_line_after_namespace":true,"constant_case":true,"elseif":true,"function_declaration":true,"indentation_type":true,"line_ending":true,"lowercase_keywords":true,"no_break_comment":true,"no_closing_tag":true,"no_spaces_after_function_name":true,"no_spaces_inside_parenthesis":true,"no_trailing_whitespace":true,"no_trailing_whitespace_in_comment":true,"single_blank_line_at_eof":true,"single_import_per_statement":true,"single_line_after_imports":true,"switch_case_semicolon_to_colon":true,"switch_case_space":true,"visibility_required":true,"encoding":true,"full_opening_tag":true},"hashes":{"src\/UuidParamConverter.php":2869219565}} -------------------------------------------------------------------------------- /src/UuidParamConverter.php: -------------------------------------------------------------------------------- 1 | registry = $registry; 30 | } 31 | 32 | public function apply(Request $request, ParamConverter $configuration) 33 | { 34 | $name = $configuration->getName(); 35 | $class = $configuration->getClass(); 36 | $options = $this->getOptions($configuration); 37 | 38 | if (null === $request->attributes->get($name, false)) { 39 | $configuration->setIsOptional(true); 40 | } 41 | 42 | $errorMessage = null; 43 | if (false === $object = $this->find($class, $request, $options, $name)) { 44 | // We could not find anything 45 | return false; 46 | } 47 | 48 | if (null === $object && false === $configuration->isOptional()) { 49 | $message = \sprintf('%s object not found by the @%s annotation.', $class, $this->getAnnotationName($configuration)); 50 | if ($errorMessage) { 51 | $message .= ' '.$errorMessage; 52 | } 53 | throw new NotFoundHttpException($message); 54 | } 55 | 56 | $request->attributes->set($name, $object); 57 | 58 | return true; 59 | } 60 | 61 | /** 62 | * {@inheritdoc} 63 | */ 64 | public function supports(ParamConverter $configuration) 65 | { 66 | // if there is no manager, this means that only Doctrine DBAL is configured 67 | if (null === $this->registry || !\count($this->registry->getManagers())) { 68 | return false; 69 | } 70 | 71 | if (null === $configuration->getClass()) { 72 | return false; 73 | } 74 | 75 | $options = $this->getOptions($configuration); 76 | 77 | // Doctrine Entity? 78 | $em = $this->getManager($options['entity_manager'], $configuration->getClass()); 79 | if (null === $em) { 80 | return false; 81 | } 82 | 83 | return !$em->getMetadataFactory()->isTransient($configuration->getClass()); 84 | } 85 | 86 | private function find($class, Request $request, $options, $name) 87 | { 88 | // If a mapping exists we should not try to auto detect this 89 | if ($options['mapping'] || $options['exclude']) { 90 | return false; 91 | } 92 | 93 | if (null === $uuid = $this->getUuid($request, $name)) { 94 | return false; 95 | } 96 | 97 | try { 98 | return $this->getManager($options['entity_manager'], $class)->getRepository($class)->findOneBy(['uuid' => $uuid]); 99 | } catch (NoResultException $e) { 100 | return; 101 | } catch (ConversionException $e) { 102 | return; 103 | } 104 | } 105 | 106 | private function getOptions(ParamConverter $configuration) 107 | { 108 | $defaultValues = [ 109 | 'entity_manager' => null, 110 | 'id' => null, 111 | 'exclude' => [], 112 | 'mapping' => [], 113 | ]; 114 | 115 | $passedOptions = $configuration->getOptions(); 116 | 117 | return \array_replace($defaultValues, $passedOptions); 118 | } 119 | 120 | private function getManager($name, $class) 121 | { 122 | if (null === $name) { 123 | return $this->registry->getManagerForClass($class); 124 | } 125 | 126 | return $this->registry->getManager($name); 127 | } 128 | 129 | private function getUuid(Request $request, $name) 130 | { 131 | $keys = [\sprintf('%s_uuid', $name), \sprintf('%sUuid', $name), 'uuid']; 132 | foreach ($keys as $key) { 133 | if ($request->attributes->has($key)) { 134 | return $request->attributes->get($key); 135 | } 136 | } 137 | 138 | return null; 139 | } 140 | 141 | private function getAnnotationName(ParamConverter $configuration) 142 | { 143 | $r = new \ReflectionClass($configuration); 144 | 145 | return $r->getShortName(); 146 | } 147 | } 148 | --------------------------------------------------------------------------------