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 |
||
0 ignored issues
–
show
|
|||
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 |
||
0 ignored issues
–
show
The doc-type
mixed(integer\NULL) could not be parsed: Expected "|" or "end of type", but got "(" at position 5. (view supported doc-types)
This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.
Loading history...
|
|||
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); |
||
0 ignored issues
–
show
It seems like
$this->em can also be of type object<Doctrine\ORM\EntityManagerInterface> ; however, Kunstmaan\NodeBundle\Ent...deTranslation::getRef() does only seem to accept object<Doctrine\ORM\EntityManager> , maybe add an additional type check?
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check: /**
* @return array|string
*/
function returnsDifferentValues($x) {
if ($x) {
return 'foo';
}
return array();
}
$x = returnsDifferentValues($y);
if (is_array($x)) {
// $x is an array.
}
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.
Loading history...
|
|||
96 | |||
97 | // Find latest position. |
||
98 | View Code Duplication | if (\is_null($position)) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
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.
Loading history...
|
|||
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 |
||
0 ignored issues
–
show
The doc-type
mixed(Node|string) could not be parsed: Expected "|" or "end of type", but got "(" at position 5. (view supported doc-types)
This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.
Loading history...
|
|||
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 |
||
0 ignored issues
–
show
The doc-type
mixed(string|Node) could not be parsed: Expected "|" or "end of type", but got "(" at position 5. (view supported doc-types)
This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.
Loading history...
|
|||
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 |
This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.