Completed
Push — master ( aba493...5356ed )
by Ruud
315:38 queued 305:00
created

Kunstmaan/FixturesBundle/Builder/PageBuilder.php (1 issue)

php_doc.return_type_not_inferrable

Documentation Minor

Upgrade to new PHP Analysis Engine

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\FixturesBundle\Builder;
4
5
use Doctrine\ORM\EntityManager;
6
use Kunstmaan\FixturesBundle\Loader\Fixture;
7
use Kunstmaan\FixturesBundle\Populator\Populator;
8
use Kunstmaan\NodeBundle\Entity\HasNodeInterface;
9
use Kunstmaan\NodeBundle\Entity\Node;
10
use Kunstmaan\NodeBundle\Entity\NodeTranslation;
11
use Kunstmaan\NodeBundle\Entity\NodeVersion;
12
use Kunstmaan\NodeBundle\Entity\StructureNode;
13
use Kunstmaan\NodeBundle\Helper\PagesConfiguration;
14
use Kunstmaan\NodeBundle\Helper\Services\ACLPermissionCreatorService;
15
use Kunstmaan\PagePartBundle\Entity\PageTemplateConfiguration;
16
use Kunstmaan\UtilitiesBundle\Helper\ClassLookup;
17
use Kunstmaan\UtilitiesBundle\Helper\Slugifier;
18
19
class PageBuilder implements BuilderInterface
20
{
21
    private $manager;
22
23
    private $userRepo;
24
25
    private $nodeRepo;
26
27
    private $nodeTranslationRepo;
28
29
    private $aclPermissionCreatorService;
30
31
    private $populator;
32
33
    private $slugifier;
34
35
    /**
36
     * @var PagesConfiguration
37
     */
38
    private $pagesConfiguration;
39
40
    public function __construct(
41
        EntityManager $em,
42
        ACLPermissionCreatorService $aclPermissionCreatorService,
43
        Populator $populator,
44
        Slugifier $slugifier,
45
        PagesConfiguration $pagesConfiguration
46
    ) {
47
        $this->manager = $em;
48
        $this->nodeRepo = $em->getRepository('KunstmaanNodeBundle:Node');
49
        $this->nodeTranslationRepo = $em->getRepository('KunstmaanNodeBundle:NodeTranslation');
50
        $this->userRepo = $em->getRepository('KunstmaanAdminBundle:User');
51
        $this->aclPermissionCreatorService = $aclPermissionCreatorService;
52
        $this->populator = $populator;
53
        $this->slugifier = $slugifier;
54
        $this->pagesConfiguration = $pagesConfiguration;
55
    }
56
57
    public function canBuild(Fixture $fixture)
58
    {
59
        if ($fixture->getEntity() instanceof HasNodeInterface) {
60
            return true;
61
        }
62
63
        return false;
64
    }
65
66
    public function preBuild(Fixture $fixture)
67
    {
68
        return;
69
    }
70
71
    public function postBuild(Fixture $fixture)
72
    {
73
        $entity = $fixture->getEntity();
74
        $fixtureParams = $fixture->getParameters();
75
        $translations = $fixture->getTranslations();
76 View Code Duplication
        if (empty($translations)) {
77
            throw new \Exception('No translations detected for page fixture ' . $fixture->getName() . ' (' . $fixture->getClass() . ')');
78
        }
79
80
        $internalName = array_key_exists('page_internal_name', $fixtureParams) ?
81
            $fixtureParams['page_internal_name'] : null;
82
83
        $rootNode = null;
84
        foreach ($fixture->getTranslations() as $language => $data) {
85
            if ($rootNode === null) {
86
                $page = $entity;
87
                $rootNode = $this->createRootNode($page, $language, $internalName, $fixtureParams);
88
                $this->manager->persist($rootNode);
89
            } else {
90
                $cloned = clone $entity;
91
                $page = $cloned;
92
                $this->manager->persist($page);
93
            }
94
95
            // Create the translationNode.
96
            $translationNode = $this->createTranslationNode($rootNode, $language, $page);
97
            if (!$page instanceof StructureNode) {
98
                $translationNode->setOnline(isset($fixtureParams['set_online']) ? $fixtureParams['set_online'] : true);
99
            }
100
101
            $fixture->addAdditional($fixture->getName() . '_' . $language, $page);
102
            $fixture->addAdditional('translationNode_' . $language, $translationNode);
103
            $fixture->addAdditional('nodeVersion_' . $language, $translationNode->getPublicNodeVersion());
104
            $fixture->addAdditional('rootNode', $rootNode);
105
106
            $this->populator->populate($translationNode, $data);
107
            $this->populator->populate($page, $data);
108 View Code Duplication
            if ($translationNode->getSlug() === null && $rootNode->getParent() !== null) {
109
                $translationNode->setSlug($this->slugifier->slugify($translationNode->getTitle()));
110
            }
111
            $this->ensureUniqueUrl($translationNode, $page);
112
113
            $this->manager->persist($translationNode);
114
            $rootNode->addNodeTranslation($translationNode);
115
        }
116
117
        $this->manager->flush();
118
        $this->aclPermissionCreatorService->createPermission($rootNode);
119
    }
120
121
    public function postFlushBuild(Fixture $fixture)
122
    {
123
        $entities = $fixture->getAdditionalEntities();
124
        $fixtureParams = $fixture->getParameters();
125
126
        foreach ($fixture->getTranslations() as $language => $data) {
127
            /** @var HasNodeInterface $page */
128
            $page = $entities[$fixture->getName() . '_' . $language];
129
            /** @var NodeTranslation $translationNode */
130
            $translationNode = $entities['translationNode_' . $language];
131
132
            $pagecreator = array_key_exists('creator', $fixtureParams) ? $fixtureParams['creator'] : 'pagecreator';
133
            $creator = $this->userRepo->findOneBy(array('username' => $pagecreator));
134
135
            $nodeVersion = new NodeVersion();
136
            $nodeVersion->setNodeTranslation($translationNode);
137
            $nodeVersion->setType('public');
138
            $nodeVersion->setOwner($creator);
139
            $nodeVersion->setRef($page);
140
141
            $translationNode->setPublicNodeVersion($nodeVersion);
142
143
            if (isset($fixtureParams['template'])) {
144
                $pageTemplateConfiguration = new PageTemplateConfiguration();
145
                $pageTemplateConfiguration->setPageId($page->getId());
146
                $pageTemplateConfiguration->setPageEntityName(ClassLookup::getClass($page));
147
                $pageTemplateConfiguration->setPageTemplate($fixtureParams['template']);
148
                $this->manager->persist($pageTemplateConfiguration);
149
            }
150
151
            $this->manager->persist($nodeVersion);
152
            $this->manager->persist($translationNode);
153
        }
154
        $this->manager->flush();
155
    }
156
157
    private function getParentNode($params, $language)
0 ignored issues
show
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
158
    {
159
        if (!isset($params['parent'])) {
160
            return;
161
        }
162
163
        $parent = $params['parent'];
164
        if ($parent instanceof Fixture) {
165
            $additionals = $parent->getAdditionalEntities();
166
            $parent = $additionals['rootNode'];
167
        } elseif (is_string($parent)) {
168
            $nodes = $this->nodeRepo->getNodesByInternalName($parent, $language, false, true);
169
            if (count($nodes) > 0) {
170
                $parent = $nodes[0];
171
            }
172
        }
173
174
        return $parent;
175
    }
176
177
    private function createRootNode($page, $language, $internalName, $fixtureParams)
178
    {
179
        $rootNode = new Node();
180
        $rootNode->setRef($page);
181
        $rootNode->setDeleted(false);
182
        $rootNode->setInternalName($internalName);
183
        $rootNode->setHiddenFromNav(
184
            isset($fixtureParams['hidden_from_nav']) ? $fixtureParams['hidden_from_nav'] : false
185
        );
186
        $parent = $this->getParentNode($fixtureParams, $language);
187
188
        if ($parent instanceof Node) {
189
            $rootNode->setParent($parent);
190
191
            if (!$this->canHaveChild($parent->getRefEntityName(), get_class($page))) {
192
                throw new \Exception(
193
                    sprintf('A %s can\'t have a %s as child. Forgot to add in allowed_children or getPossibleChildTypes?', $parent->getRefEntityName(), get_class($page))
194
                );
195
            }
196
        }
197
198
        return $rootNode;
199
    }
200
201
    private function createTranslationNode(Node $rootNode, $language, HasNodeInterface $page)
202
    {
203
        $translationNode = new NodeTranslation();
204
        $translationNode
205
            ->setNode($rootNode)
206
            ->setLang($language)
207
            ->setTitle($page->getTitle())
208
            ->setOnline(false)
209
            ->setWeight(0);
210
211
        return $translationNode;
212
    }
213
214
    private function ensureUniqueUrl(NodeTranslation $translation, HasNodeInterface $page)
215
    {
216
        if ($page instanceof StructureNode) {
217
            $translation->setSlug('');
218
            $translation->setUrl($translation->getFullSlug());
219
220
            return $translation;
221
        }
222
223
        $translation->setUrl($translation->getFullSlug());
224
225
        // Find all translations with this new URL, whose nodes are not deleted.
226
        $translationWithSameUrl = $this->nodeTranslationRepo->getNodeTranslationForUrl($translation->getUrl(), $translation->getLang(), false, $translation);
227
228
        if ($translationWithSameUrl instanceof NodeTranslation) {
229
            $translation->setSlug($this->slugifier->slugify($this->incrementString($translation->getSlug())));
230
            $this->ensureUniqueUrl($translation, $page);
231
        }
232
233
        return $translation;
234
    }
235
236 View Code Duplication
    private function incrementString($string, $append = '-v')
237
    {
238
        $finalDigitGrabberRegex = '/\d+$/';
239
        $matches = array();
240
241
        preg_match($finalDigitGrabberRegex, $string, $matches);
242
243
        if (count($matches) > 0) {
244
            $digit = (int) $matches[0];
245
            ++$digit;
246
247
            // Replace the integer with the new digit.
248
            return preg_replace($finalDigitGrabberRegex, $digit, $string);
249
        } else {
250
            return $string . $append . '1';
251
        }
252
    }
253
254
    /**
255
     * @param string $parentPageClass
256
     * @param string $childPageClass
257
     *
258
     * @return bool
259
     */
260
    private function canHaveChild($parentPageClass, $childPageClass)
261
    {
262
        $childTypes = $this->pagesConfiguration->getPossibleChildTypes($parentPageClass);
263
264
        foreach ($childTypes as $childType) {
265
            if ($childType['class'] == $childPageClass) {
266
                return true;
267
            }
268
        }
269
270
        return false;
271
    }
272
}
273