Completed
Push — 5.0 ( a48099...63af02 )
by
unknown
11:33
created

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

Severity

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
    private $userRepo;
23
    private $nodeRepo;
24
    private $nodeTranslationRepo;
25
    private $aclPermissionCreatorService;
26
    private $populator;
27
    private $slugifier;
28
29
    /**
30
     * @var PagesConfiguration
31
     */
32
    private $pagesConfiguration;
33
34
    public function __construct(
35
        EntityManager $em,
36
        ACLPermissionCreatorService $aclPermissionCreatorService,
37
        Populator $populator,
38
        Slugifier $slugifier,
39
        PagesConfiguration $pagesConfiguration
40
    ) {
41
        $this->manager = $em;
42
        $this->nodeRepo = $em->getRepository('KunstmaanNodeBundle:Node');
43
        $this->nodeTranslationRepo = $em->getRepository('KunstmaanNodeBundle:NodeTranslation');
44
        $this->userRepo = $em->getRepository('KunstmaanAdminBundle:User');
45
        $this->aclPermissionCreatorService = $aclPermissionCreatorService;
46
        $this->populator = $populator;
47
        $this->slugifier = $slugifier;
48
        $this->pagesConfiguration = $pagesConfiguration;
49
    }
50
51
    public function canBuild(Fixture $fixture)
52
    {
53
        if ($fixture->getEntity() instanceof HasNodeInterface) {
54
            return true;
55
        }
56
57
        return false;
58
    }
59
60
    public function preBuild(Fixture $fixture)
61
    {
62
        return;
63
    }
64
65
    public function postBuild(Fixture $fixture)
66
    {
67
        $entity = $fixture->getEntity();
68
        $fixtureParams = $fixture->getParameters();
69
        $translations = $fixture->getTranslations();
70 View Code Duplication
        if (empty($translations)) {
71
            throw new \Exception('No translations detected for page fixture ' . $fixture->getName() . ' (' . $fixture->getClass() . ')');
72
        }
73
74
        $internalName = array_key_exists('page_internal_name', $fixtureParams) ?
75
            $fixtureParams['page_internal_name'] : null;
76
77
        $rootNode = null;
78
        foreach ($fixture->getTranslations() as $language => $data) {
79
            if ($rootNode === null) {
80
                $page = $entity;
81
                $rootNode = $this->createRootNode($page, $language, $internalName, $fixtureParams);
82
                $this->manager->persist($rootNode);
83
            } else {
84
                $cloned = clone $entity;
85
                $page = $cloned;
86
                $this->manager->persist($page);
87
            }
88
89
            // Create the translationNode.
90
            $translationNode = $this->createTranslationNode($rootNode, $language, $page);
91
            if (!$page instanceof StructureNode) {
92
                $translationNode->setOnline(isset($fixtureParams['set_online']) ? $fixtureParams['set_online'] : true);
93
            }
94
95
            $fixture->addAdditional($fixture->getName() . '_' . $language, $page);
96
            $fixture->addAdditional('translationNode_' . $language, $translationNode);
97
            $fixture->addAdditional('nodeVersion_' . $language, $translationNode->getPublicNodeVersion());
98
            $fixture->addAdditional('rootNode', $rootNode);
99
100
            $this->populator->populate($translationNode, $data);
101
            $this->populator->populate($page, $data);
102 View Code Duplication
            if ($translationNode->getSlug() === null && $rootNode->getParent() !== null) {
103
                $translationNode->setSlug($this->slugifier->slugify($translationNode->getTitle()));
104
            }
105
            $this->ensureUniqueUrl($translationNode, $page);
106
107
            $this->manager->persist($translationNode);
108
            $rootNode->addNodeTranslation($translationNode);
109
        }
110
111
        $this->manager->flush();
112
        $this->aclPermissionCreatorService->createPermission($rootNode);
113
    }
114
115
    public function postFlushBuild(Fixture $fixture)
116
    {
117
        $entities = $fixture->getAdditionalEntities();
118
        $fixtureParams = $fixture->getParameters();
119
120
        foreach ($fixture->getTranslations() as $language => $data) {
121
            /** @var HasNodeInterface $page */
122
            $page = $entities[$fixture->getName() . '_' . $language];
123
            /** @var NodeTranslation $translationNode */
124
            $translationNode = $entities['translationNode_' . $language];
125
126
            $pagecreator = array_key_exists('creator', $fixtureParams) ? $fixtureParams['creator'] : 'pagecreator';
127
            $creator = $this->userRepo->findOneBy(array('username' => $pagecreator));
128
129
            $nodeVersion = new NodeVersion();
130
            $nodeVersion->setNodeTranslation($translationNode);
131
            $nodeVersion->setType('public');
132
            $nodeVersion->setOwner($creator);
0 ignored issues
show
$creator is of type object, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

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