Completed
Push — master ( ae5e03...0447ee )
by Jeroen
10:35 queued 04:37
created

NodeBundle/Helper/Services/PageCreatorService.php (2 issues)

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\NodeBundle\Helper\Services;
4
5
use Doctrine\ORM\EntityManager;
6
use Doctrine\ORM\ORMException;
7
use Kunstmaan\AdminBundle\Repository\UserRepository;
8
use Kunstmaan\NodeBundle\Entity\HasNodeInterface;
9
use Kunstmaan\NodeBundle\Entity\Node;
10
use Kunstmaan\NodeBundle\Entity\NodeTranslation;
11
use Kunstmaan\NodeBundle\Repository\NodeRepository;
12
use Kunstmaan\PagePartBundle\Helper\HasPagePartsInterface;
13
use Kunstmaan\SeoBundle\Entity\Seo;
14
use Kunstmaan\SeoBundle\Repository\SeoRepository;
15
use Symfony\Component\DependencyInjection\ContainerInterface;
16
17
/**
18
 * Service to create new pages.
19
 */
20
class PageCreatorService
21
{
22
    /**
23
     * @var EntityManager
24
     */
25
    protected $entityManager;
26
27
    /**
28
     * @var ACLPermissionCreatorService
29
     */
30
    protected $aclPermissionCreatorService;
31
32
    /**
33
     * @var string
34
     */
35
    protected $userEntityClass;
36
37
    public function setEntityManager($entityManager)
38
    {
39
        $this->entityManager = $entityManager;
40
    }
41
42
    public function setACLPermissionCreatorService($aclPermissionCreatorService)
43
    {
44
        $this->aclPermissionCreatorService = $aclPermissionCreatorService;
45
    }
46
47
    public function setUserEntityClass($userEntityClass)
48
    {
49
        $this->userEntityClass = $userEntityClass;
50
    }
51
52
    /**
53
     * Sets the Container. This is still here for backwards compatibility.
54
     *
55
     * The ContainerAwareInterface has been removed so the container won't be injected automatically.
56
     * This function is just there for code that calls it manually.
57
     *
58
     * @param ContainerInterface $container a ContainerInterface instance
59
     *
60
     * @api
61
     */
62
    public function setContainer(ContainerInterface $container = null)
63
    {
64
        $this->setEntityManager($container->get('doctrine.orm.entity_manager'));
65
        $this->setACLPermissionCreatorService($container->get('kunstmaan_node.acl_permission_creator_service'));
66
        $this->setUserEntityClass($container->getParameter('fos_user.model.user.class'));
67
    }
68
69
    /**
70
     * @param HasNodeInterface $pageTypeInstance the page
71
     * @param array            $translations     Containing arrays. Sample:
72
     *                                           [
73
     *                                           [   "language" => "nl",
74
     *                                           "callback" => function($page, $translation) {
75
     *                                           $translation->setTitle('NL titel');
76
     *                                           }
77
     *                                           ],
78
     *                                           [   "language" => "fr",
79
     *                                           "callback" => function($page, $translation) {
80
     *                                           $translation->setTitle('FR titel');
81
     *                                           }
82
     *                                           ]
83
     *                                           ]
84
     *                                           Perhaps it's cleaner when you create one array and append another array for each language.
85
     * @param array            $options          Possible options:
86
     *                                           parent: type node, nodetransation or page.
87
     *                                           page_internal_name: string. name the page will have in the database.
88
     *                                           set_online: bool. if true the page will be set as online after creation.
89
     *                                           hidden_from_nav: bool. if true the page will not be show in the navigation
90
     *                                           creator: username
91
     *
92
     * Automatically calls the ACL + sets the slugs to empty when the page is an Abstract node.
93
     *
94
     * @return Node the new node for the page
0 ignored issues
show
Should the return type not be Node|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
95
     *
96
     * @throws \InvalidArgumentException
97
     */
98
    public function createPage(HasNodeInterface $pageTypeInstance, array $translations, array $options = array())
99
    {
100
        if (\is_null($options)) {
101
            $options = array();
102
        }
103
104
        if (\is_null($translations) || (\count($translations) == 0)) {
105
            throw new \InvalidArgumentException('There has to be at least 1 translation in the translations array');
106
        }
107
108
        $em = $this->entityManager;
109
110
        /** @var NodeRepository $nodeRepo */
111
        $nodeRepo = $em->getRepository(Node::class);
112
        /** @var UserRepository $userRepo */
113
        $userRepo = $em->getRepository($this->userEntityClass);
114
        /* @var SeoRepository $seoRepo */
115
        try {
116
            $seoRepo = $em->getRepository(Seo::class);
117
        } catch (ORMException $e) {
118
            $seoRepo = null;
119
        }
120
121
        $pagecreator = \array_key_exists('creator', $options) ? $options['creator'] : 'pagecreator';
122
123
        if ($pagecreator instanceof $this->userEntityClass) {
124
            $creator = $pagecreator;
125
        } else {
126
            $creator = $userRepo->findOneBy(array('username' => $pagecreator));
127
        }
128
129
        $parent = isset($options['parent']) ? $options['parent'] : null;
130
131
        $pageInternalName = isset($options['page_internal_name']) ? $options['page_internal_name'] : null;
132
133
        $setOnline = isset($options['set_online']) ? $options['set_online'] : false;
134
135
        // We need to get the language of the first translation so we can create the rootnode.
136
        // This will also create a translationnode for that language attached to the rootnode.
137
        $first = true;
138
        $rootNode = null;
139
140
        /* @var \Kunstmaan\NodeBundle\Repository\NodeTranslationRepository $nodeTranslationRepo*/
141
        $nodeTranslationRepo = $em->getRepository(NodeTranslation::class);
142
143
        foreach ($translations as $translation) {
144
            $language = $translation['language'];
145
            $callback = $translation['callback'];
146
147
            $translationNode = null;
0 ignored issues
show
$translationNode is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
148
            if ($first) {
149
                $first = false;
150
151
                $em->persist($pageTypeInstance);
152
                $em->flush($pageTypeInstance);
153
154
                // Fetch the translation instead of creating it.
155
                // This returns the rootnode.
156
                $rootNode = $nodeRepo->createNodeFor($pageTypeInstance, $language, $creator, $pageInternalName);
157
158
                if (\array_key_exists('hidden_from_nav', $options)) {
159
                    $rootNode->setHiddenFromNav($options['hidden_from_nav']);
160
                }
161
162
                if (!\is_null($parent)) {
163
                    if ($parent instanceof HasPagePartsInterface) {
164
                        $parent = $nodeRepo->getNodeFor($parent);
165
                    }
166
                    $rootNode->setParent($parent);
167
                }
168
169
                $em->persist($rootNode);
170
                $em->flush($rootNode);
171
172
                $translationNode = $rootNode->getNodeTranslation($language, true);
173
            } else {
174
                // Clone the $pageTypeInstance.
175
                $pageTypeInstance = clone $pageTypeInstance;
176
177
                $em->persist($pageTypeInstance);
178
                $em->flush($pageTypeInstance);
179
180
                // Create the translationnode.
181
                $translationNode = $nodeTranslationRepo->createNodeTranslationFor($pageTypeInstance, $language, $rootNode, $creator);
182
            }
183
184
            // Make SEO.
185
            $seo = null;
186
187
            if (!\is_null($seoRepo)) {
188
                $seo = $seoRepo->findOrCreateFor($pageTypeInstance);
189
            }
190
191
            $callback($pageTypeInstance, $translationNode, $seo);
192
193
            // Overwrite the page title with the translated title
194
            $pageTypeInstance->setTitle($translationNode->getTitle());
195
            $em->persist($pageTypeInstance);
196
            $em->persist($translationNode);
197
            $em->flush($pageTypeInstance);
198
            $em->flush($translationNode);
199
200
            $translationNode->setOnline($setOnline);
201
202
            if (!\is_null($seo)) {
203
                $em->persist($seo);
204
                $em->flush($seo);
205
            }
206
207
            $em->persist($translationNode);
208
            $em->flush($translationNode);
209
        }
210
211
        // ACL
212
        $this->aclPermissionCreatorService->createPermission($rootNode);
213
214
        return $rootNode;
215
    }
216
}
217