These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace Kunstmaan\PagePartBundle\Helper\Services; |
||
4 | |||
5 | use Doctrine\ORM\EntityManager; |
||
6 | use Doctrine\ORM\EntityManagerInterface; |
||
7 | use Kunstmaan\AdminBundle\Entity\EntityInterface; |
||
8 | use Kunstmaan\NodeBundle\Entity\NodeTranslation; |
||
9 | use Kunstmaan\NodeBundle\Repository\NodeRepository; |
||
10 | use Kunstmaan\NodeBundle\Repository\NodeTranslationRepository; |
||
11 | use Kunstmaan\PagePartBundle\Entity\PageTemplateConfiguration; |
||
12 | use Kunstmaan\PagePartBundle\Helper\HasPagePartsInterface; |
||
13 | use Kunstmaan\PagePartBundle\Helper\HasPageTemplateInterface; |
||
14 | use Kunstmaan\PagePartBundle\Helper\PagePartInterface; |
||
15 | use Kunstmaan\PagePartBundle\Repository\PagePartRefRepository; |
||
16 | use Kunstmaan\PagePartBundle\Repository\PageTemplateConfigurationRepository; |
||
17 | use Kunstmaan\UtilitiesBundle\Helper\ClassLookup; |
||
18 | |||
19 | /** |
||
20 | * A class to facilitate the adding of PageParts to existing pages. |
||
21 | * |
||
22 | * NOTE: There is a similar implementation for adding pages. See the NodeBundle for more on this. |
||
23 | */ |
||
24 | class PagePartCreatorService |
||
25 | { |
||
26 | /** |
||
27 | * @var EntityManagerInterface|EntityManager |
||
28 | */ |
||
29 | protected $em; |
||
30 | |||
31 | /** |
||
32 | * @var PagePartRefRepository |
||
33 | */ |
||
34 | protected $pagePartRepo; |
||
35 | |||
36 | /** |
||
37 | * @var NodeTranslationRepository |
||
38 | */ |
||
39 | protected $translationRepo; |
||
40 | |||
41 | /** |
||
42 | * @var NodeRepository |
||
43 | */ |
||
44 | protected $nodeRepo; |
||
45 | |||
46 | /** |
||
47 | * Sets the EntityManager dependency. |
||
48 | * |
||
49 | * @param EntityManagerInterface $em |
||
50 | */ |
||
51 | public function setEntityManager(EntityManagerInterface $em) |
||
52 | { |
||
53 | $this->em = $em; |
||
54 | // Because these repositories are shared between the different functions it's |
||
55 | // easier to make them available in the class. |
||
56 | $this->pagePartRepo = $em->getRepository('KunstmaanPagePartBundle:PagePartRef'); |
||
57 | $this->translationRepo = $em->getRepository('KunstmaanNodeBundle:NodeTranslation'); |
||
58 | $this->nodeRepo = $em->getRepository('KunstmaanNodeBundle:Node'); |
||
59 | } |
||
60 | |||
61 | /** |
||
62 | * @return EntityManagerInterface |
||
63 | */ |
||
64 | public function getEntityManager() |
||
65 | { |
||
66 | return $this->em; |
||
67 | } |
||
68 | |||
69 | /** |
||
70 | * Add a single pagepart to an existing page for a specific language, in an optional position. |
||
71 | * |
||
72 | * @param mixed(Node|string) $nodeOrInternalName |
||
73 | * A Node instance or the internal name. |
||
74 | * When the internal name is passed we'll get the node instance. |
||
75 | * Based on the language we'll locate the correct Page instance. |
||
76 | * @param pagePartInterface $pagePart |
||
77 | * A completely configured pagepart for this language |
||
78 | * @param string $language |
||
79 | * The languagecode. nl|fr|en|.. . Just one. |
||
80 | * @param string $context |
||
81 | * Where you want the pagepart to be |
||
82 | * @param mixed(integer\NULL) $position |
||
83 | * Leave null if you want to append at the end. |
||
84 | * Otherwise set a position you would like and it'll inject the pagepart in that position. |
||
85 | * It won't override pageparts but it will rather inject itself in that position and |
||
86 | * push the other pageparts down. |
||
87 | */ |
||
88 | public function addPagePartToPage($nodeOrInternalName, PagePartInterface $pagePart, $language, $context = 'main', $position = null) |
||
89 | { |
||
90 | // Find the correct page instance. |
||
91 | $node = $this->getNode($nodeOrInternalName); |
||
92 | /** @var $translation NodeTranslation */ |
||
93 | $translation = $node->getNodeTranslation($language, true); |
||
94 | /** @var HasPagePartsInterface $page */ |
||
95 | $page = $translation->getRef($this->em); |
||
96 | |||
97 | // Find latest position. |
||
98 | View Code Duplication | if (\is_null($position)) { |
|
0 ignored issues
–
show
|
|||
99 | $pageParts = $this->pagePartRepo->getPagePartRefs($page, $context); |
||
100 | $position = \count($pageParts) + 1; |
||
101 | } |
||
102 | |||
103 | $this->em->persist($pagePart); |
||
104 | $this->em->flush(); |
||
105 | |||
106 | $this->pagePartRepo->addPagePart($page, $pagePart, $position, $context); |
||
107 | } |
||
108 | |||
109 | /** |
||
110 | * A helper function to more easily append multiple pageparts in different manners. |
||
111 | * |
||
112 | * @param mixed(Node|string) $nodeOrInternalName |
||
113 | * The node that you'd like to append the pageparts to. It's also possible to provide an internalname. |
||
114 | * @param array $structure |
||
115 | * The structure array is something like this: |
||
116 | * |
||
117 | * array('main' => array( |
||
118 | * function() { return new DummyPagePart('A') }, function() { return new DummyPagePart('B') } |
||
119 | * ), 'banners' => array($awesomeBanner)); |
||
120 | * |
||
121 | * So it's an array containing the pageparts per region. Each pagepart is returned by a function. |
||
122 | * This is clean because we don't have to bother with variablenames which we have to remember to pass |
||
123 | * to the pagecreatorservice at the right time. With this method it's impossible to assign a wrong pagepart to a page. |
||
124 | * Unless you provide the incorrect page oviously ... . |
||
125 | * |
||
126 | * You can also include variables in the pagepart arrays if you want. |
||
127 | * |
||
128 | * Or optionally you can use the results of the getCreatorArgumentsForPagePartAndProperties function instead of an anonymous function. |
||
129 | * @param string $language |
||
130 | * The language of the translation you want to append to |
||
131 | * |
||
132 | * @throws \LogicException |
||
133 | */ |
||
134 | public function addPagePartsToPage($nodeOrInternalName, array $structure, $language) |
||
135 | { |
||
136 | $node = $this->getNode($nodeOrInternalName); |
||
137 | |||
138 | // First instantiate all PageParts. This way no PageParts will be saved if there is an issue instantiating some of them. |
||
139 | $instantiatedPageParts = array(); |
||
140 | foreach ($structure as $context => $pageParts) { |
||
141 | $instantiatedPageParts[$context] = array(); |
||
142 | |||
143 | foreach ($pageParts as $pagePartOrFunction) { |
||
144 | if (\is_callable($pagePartOrFunction)) { |
||
145 | $pagePartOrFunction = $pagePartOrFunction(); |
||
146 | |||
147 | if (!isset($pagePartOrFunction) || is_null($pagePartOrFunction)) { |
||
148 | throw new \LogicException('A function returned nothing for a pagepart. Make sure you return your instantiated pageparts in your anonymous functions.'); |
||
149 | } |
||
150 | } |
||
151 | if (!$pagePartOrFunction instanceof PagePartInterface) { |
||
152 | throw new \LogicException('Detected a supposed pagepart that did not implement the PagePartInterface.'); |
||
153 | } |
||
154 | |||
155 | $instantiatedPageParts[$context][] = $pagePartOrFunction; |
||
156 | } |
||
157 | } |
||
158 | |||
159 | // All good. We can start saving. |
||
160 | foreach ($instantiatedPageParts as $context => $pageParts) { |
||
161 | foreach ($pageParts as $pagePart) { |
||
162 | $this->addPagePartToPage($node, $pagePart, $language, $context); |
||
163 | } |
||
164 | } |
||
165 | } |
||
166 | |||
167 | /** |
||
168 | * @param mixed(Node|string) $nodeOrInternalName |
||
169 | * @param string $language |
||
170 | * @param string $templateName |
||
171 | */ |
||
172 | public function setPageTemplate($nodeOrInternalName, $language, $templateName) |
||
173 | { |
||
174 | $node = $this->getNode($nodeOrInternalName); |
||
175 | /** @var $translation NodeTranslation */ |
||
176 | $translation = $node->getNodeTranslation($language, true); |
||
177 | /** @var HasPageTemplateInterface|EntityInterface $page */ |
||
178 | $page = $translation->getRef($this->em); |
||
179 | |||
180 | /** @var PageTemplateConfigurationRepository $repo */ |
||
181 | $repo = $this->em->getRepository('KunstmaanPagePartBundle:PageTemplateConfiguration'); |
||
182 | $pageTemplateConfiguration = $repo->findFor($page); |
||
183 | if ($pageTemplateConfiguration) { |
||
184 | $pageTemplateConfiguration->setPageTemplate($templateName); |
||
185 | } else { |
||
186 | $pageTemplateConfiguration = new PageTemplateConfiguration(); |
||
187 | $pageTemplateConfiguration->setPageId($page->getId()); |
||
188 | $pageTemplateConfiguration->setPageEntityName(ClassLookup::getClass($page)); |
||
189 | $pageTemplateConfiguration->setPageTemplate($templateName); |
||
190 | } |
||
191 | |||
192 | $this->em->persist($pageTemplateConfiguration); |
||
193 | $this->em->flush(); |
||
194 | } |
||
195 | |||
196 | /** |
||
197 | * A helper function to express what pagepart you want. |
||
198 | * |
||
199 | * It just accepts a classname and an array of setter functions with their requested values. |
||
200 | * |
||
201 | * It'll return an anonymous function which instantiates the pagepart. |
||
202 | * |
||
203 | * @param string $pagePartClassName the full class name of the pagepart you want to instantiate |
||
204 | * @param array $setters An array of setternames and their values. array('setName' => 'Kim', 'isDeveloper' => true) |
||
0 ignored issues
–
show
Should the type for parameter
$setters not be null|array ? Also, consider making the array more specific, something like array<String> , or String[] .
This check looks for It makes a suggestion as to what type it considers more descriptive. In addition it
looks for parameters that have the generic type Most often this is a case of a parameter that can be null in addition to its declared types.
Loading history...
|
|||
205 | * |
||
206 | * @return callable the function that will instantiate a pagepart |
||
207 | */ |
||
208 | public function getCreatorArgumentsForPagePartAndProperties($pagePartClassName, array $setters = null) |
||
209 | { |
||
210 | return function () use ($pagePartClassName, $setters) { |
||
211 | $pp = new $pagePartClassName(); |
||
212 | |||
213 | if (!\is_null($setters)) { |
||
214 | foreach ($setters as $setter => $value) { |
||
215 | \call_user_func(array($pp, $setter), $value); |
||
216 | } |
||
217 | } |
||
218 | |||
219 | return $pp; |
||
220 | }; |
||
221 | } |
||
222 | |||
223 | /** |
||
224 | * @param mixed(string|Node) $nodeOrInternalName |
||
225 | * |
||
226 | * @return object |
||
227 | */ |
||
228 | private function getNode($nodeOrInternalName) |
||
229 | { |
||
230 | if (\is_string($nodeOrInternalName)) { |
||
231 | return $this->nodeRepo->findOneBy(array('internalName' => $nodeOrInternalName)); |
||
232 | } |
||
233 | |||
234 | return $nodeOrInternalName; |
||
235 | } |
||
236 | } |
||
237 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.