33namespace Utilitte \Nette \Traits \Application ;
44
55use Doctrine \ORM \EntityManagerInterface ;
6+ use LogicException ;
7+ use Nette \Utils \Strings ;
68use Utilitte \Nette \Exceptions \EntityIsNotValid ;
79use Utilitte \Nette \Exceptions \EntityNotFound ;
810use Utilitte \Nette \Exceptions \InvalidArgumentException ;
911
1012trait LazyEntityGetter
1113{
1214
13- /**
14- * @var mixed[]
15- * @internal
16- */
15+ /** @var mixed[] */
1716 private ?array $ _entityMeta = null ;
1817
1918 /** @var callable[] */
2019 private array $ _lazyGetterValidators = [];
2120
22- /** @internal */
2321 private EntityManagerInterface $ _entityMetaEm ;
2422
2523 final public function injectLazyEntityGetter (EntityManagerInterface $ em ): void
@@ -37,28 +35,47 @@ final protected function addLazyEntityGetterValidator(callable $validator): void
3735 * @param class-string<T> $class
3836 * @return T|null
3937 */
40- final protected function getOptionalEntity (string $ class , string $ parameterName = 'id ' ): ?object
38+ final protected function getEntityIfParameterPresented (string $ class , string $ parameterName = 'id ' , array $ checkParameters = [] ): ?object
4139 {
4240 if ($ this ->getParameter ($ parameterName ) === null ) {
4341 return null ;
4442 }
4543
46- return $ this ->getEntity ($ class , $ parameterName );
44+ return $ this ->getEntity ($ class , $ parameterName, $ checkParameters );
4745 }
4846
49- /**
50- * @template T
51- * @param class-string<T> $class
52- * @return T
53- */
54- final protected function getEntity (string $ class , string $ parameterName = 'id ' ): object
47+ final protected function getNullableEntity (string $ class , string $ parameterName = 'id ' , array $ checkParameters = []): ?object
5548 {
5649 if ($ this ->_entityMeta === null ) {
50+ $ object = $ this ->getOptionalEntity ($ class , $ parameterName , $ checkParameters );
5751 $ id = $ this ->getParameter ($ parameterName );
52+
53+ if ($ id === null ) {
54+ return null ;
55+ }
56+
5857 $ object = $ this ->_entityMetaEm ->find ($ class , $ id );
5958
6059 if (!$ object ) {
61- throw new EntityNotFound ($ class , $ id );
60+ return null ;
61+ }
62+
63+ // checks parameters if equals or fix
64+ $ redirect = false ;
65+ $ parameters = $ this ->getParameters ();
66+ foreach ($ checkParameters as $ name => $ value ) {
67+ $ parameter = $ parameters [$ name ] ?? null ;
68+ if ($ parameter === null && $ value === null ) {
69+ continue ;
70+ }
71+ if ($ parameter !== ($ webalize = Strings::webalize ((string ) $ value ))) {
72+ $ parameters [$ name ] = $ webalize ;
73+ $ redirect = true ;
74+ }
75+ }
76+
77+ if ($ redirect ) {
78+ $ this ->redirectPermanent ('this ' , $ parameters );
6279 }
6380
6481 foreach ($ this ->_lazyGetterValidators as $ validator ) {
@@ -68,16 +85,42 @@ final protected function getEntity(string $class, string $parameterName = 'id'):
6885 }
6986
7087 $ this ->_entityMeta = [
88+ 'parameter ' => $ id ,
7189 'class ' => $ class ,
7290 'object ' => $ object ,
7391 ];
7492 } elseif ($ this ->_entityMeta ['class ' ] !== $ class ) {
7593 throw new InvalidArgumentException (
76- sprintf ('Entity %s already requested, cannot request %s entity ' , $ this ->_entityMeta ['class ' ], $ class )
94+ sprintf ('Entity %s already requested, cannot request %s entity. ' , $ this ->_entityMeta ['class ' ], $ class )
95+ );
96+ } elseif ($ this ->_entityMeta ['parameter ' ] !== $ this ->getParameter ($ parameterName )) {
97+ throw new LogicException (
98+ sprintf (
99+ 'Entity %s with id %s requested, cannot change id to %s. ' ,
100+ $ this ->_entityMeta ['class ' ],
101+ (string ) $ this ->_entityMeta ['parameter ' ],
102+ (string ) $ this ->getParameter ($ parameterName )
103+ )
77104 );
78105 }
79106
80107 return $ this ->_entityMeta ['object ' ];
81108 }
82109
110+ /**
111+ * @template T
112+ * @param class-string<T> $class
113+ * @return T
114+ */
115+ final protected function getEntity (string $ class , string $ parameterName = 'id ' , array $ checkParameters = []): object
116+ {
117+ $ object = $ this ->getNullableEntity ($ class , $ parameterName , $ checkParameters );
118+
119+ if (!$ object ) {
120+ throw new EntityNotFound ($ class , $ id );
121+ }
122+
123+ return $ object ;
124+ }
125+
83126}
0 commit comments