Issues (3099)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

Helper/Services/PagePartCreatorService.php (7 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\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\Node;
9
use Kunstmaan\NodeBundle\Entity\NodeTranslation;
10
use Kunstmaan\NodeBundle\Repository\NodeRepository;
11
use Kunstmaan\NodeBundle\Repository\NodeTranslationRepository;
12
use Kunstmaan\PagePartBundle\Entity\PagePartRef;
13
use Kunstmaan\PagePartBundle\Entity\PageTemplateConfiguration;
14
use Kunstmaan\PagePartBundle\Helper\HasPagePartsInterface;
15
use Kunstmaan\PagePartBundle\Helper\HasPageTemplateInterface;
16
use Kunstmaan\PagePartBundle\Helper\PagePartInterface;
17
use Kunstmaan\PagePartBundle\Repository\PagePartRefRepository;
18
use Kunstmaan\PagePartBundle\Repository\PageTemplateConfigurationRepository;
19
use Kunstmaan\UtilitiesBundle\Helper\ClassLookup;
20
21
/**
22
 * A class to facilitate the adding of PageParts to existing pages.
23
 *
24
 * NOTE: There is a similar implementation for adding pages. See the NodeBundle for more on this.
25
 */
26
class PagePartCreatorService
27
{
28
    /**
29
     * @var EntityManagerInterface|EntityManager
30
     */
31
    protected $em;
32
33
    /**
34
     * @var PagePartRefRepository
35
     */
36
    protected $pagePartRepo;
37
38
    /**
39
     * @var NodeTranslationRepository
40
     */
41
    protected $translationRepo;
42
43
    /**
44
     * @var NodeRepository
45
     */
46
    protected $nodeRepo;
47
48
    /**
49
     * Sets the EntityManager dependency.
50
     *
51
     * @param EntityManagerInterface $em
52
     */
53
    public function setEntityManager(EntityManagerInterface $em)
54
    {
55
        $this->em = $em;
56
        // Because these repositories are shared between the different functions it's
57
        // easier to make them available in the class.
58
        $this->pagePartRepo = $em->getRepository(PagePartRef::class);
59
        $this->translationRepo = $em->getRepository(NodeTranslation::class);
60
        $this->nodeRepo = $em->getRepository(Node::class);
61
    }
62
63
    /**
64
     * @return EntityManagerInterface
65
     */
66
    public function getEntityManager()
67
    {
68
        return $this->em;
69
    }
70
71
    /**
72
     * Add a single pagepart to an existing page for a specific language, in an optional position.
73
     *
74
     * @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...
75
     *                                                A Node instance or the internal name.
76
     *                                                When the internal name is passed we'll get the node instance.
77
     *                                                Based on the language we'll locate the correct Page instance.
78
     * @param pagePartInterface   $pagePart
79
     *                                                A completely configured pagepart for this language
80
     * @param string              $language
81
     *                                                The languagecode. nl|fr|en|.. . Just one.
82
     * @param string              $context
83
     *                                                Where you want the pagepart to be
84
     * @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...
85
     *                                                Leave null if you want to append at the end.
86
     *                                                Otherwise set a position you would like and it'll inject the pagepart in that position.
87
     *                                                It won't override pageparts but it will rather inject itself in that position and
88
     *                                                push the other pageparts down.
89
     */
90
    public function addPagePartToPage($nodeOrInternalName, PagePartInterface $pagePart, $language, $context = 'main', $position = null)
91
    {
92
        // Find the correct page instance.
93
        $node = $this->getNode($nodeOrInternalName);
94
        /** @var $translation NodeTranslation */
95
        $translation = $node->getNodeTranslation($language, true);
96
        /** @var HasPagePartsInterface $page */
97
        $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...
98
99
        // Find latest position.
100 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...
101
            $pageParts = $this->pagePartRepo->getPagePartRefs($page, $context);
102
            $position = \count($pageParts) + 1;
103
        }
104
105
        $this->em->persist($pagePart);
106
        $this->em->flush();
107
108
        $this->pagePartRepo->addPagePart($page, $pagePart, $position, $context);
109
    }
110
111
    /**
112
     * A helper function to more easily append multiple pageparts in different manners.
113
     *
114
     * @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...
115
     *                                               The node that you'd like to append the pageparts to. It's also possible to provide an internalname.
116
     * @param array              $structure
117
     *                                               The structure array is something like this:
118
     *
119
     *      array('main' => array(
120
     *          function() { return new DummyPagePart('A') }, function() { return new DummyPagePart('B') }
121
     *       ), 'banners' => array($awesomeBanner));
122
     *
123
     *      So it's an array containing the pageparts per region. Each pagepart is returned by a function.
124
     *      This is clean because we don't have to bother with variablenames which we have to remember to pass
125
     *      to the pagecreatorservice at the right time. With this method it's impossible to assign a wrong pagepart to a page.
126
     *      Unless you provide the incorrect page oviously ... .
127
     *
128
     *      You can also include variables in the pagepart arrays if you want.
129
     *
130
     *      Or optionally you can use the results of the getCreatorArgumentsForPagePartAndProperties function instead of an anonymous function.
131
     * @param string $language
132
     *                         The language of the translation you want to append to
133
     *
134
     * @throws \LogicException
135
     */
136
    public function addPagePartsToPage($nodeOrInternalName, array $structure, $language)
137
    {
138
        $node = $this->getNode($nodeOrInternalName);
139
140
        // First instantiate all PageParts. This way no PageParts will be saved if there is an issue instantiating some of them.
141
        $instantiatedPageParts = array();
142
        foreach ($structure as $context => $pageParts) {
143
            $instantiatedPageParts[$context] = array();
144
145
            foreach ($pageParts as $pagePartOrFunction) {
146
                if (\is_callable($pagePartOrFunction)) {
147
                    $pagePartOrFunction = $pagePartOrFunction();
148
149
                    if (!isset($pagePartOrFunction) || is_null($pagePartOrFunction)) {
150
                        throw new \LogicException('A function returned nothing for a pagepart. Make sure you return your instantiated pageparts in your anonymous functions.');
151
                    }
152
                }
153
                if (!$pagePartOrFunction instanceof PagePartInterface) {
154
                    throw new \LogicException('Detected a supposed pagepart that did not implement the PagePartInterface.');
155
                }
156
157
                $instantiatedPageParts[$context][] = $pagePartOrFunction;
158
            }
159
        }
160
161
        // All good. We can start saving.
162
        foreach ($instantiatedPageParts as $context => $pageParts) {
163
            foreach ($pageParts as $pagePart) {
164
                $this->addPagePartToPage($node, $pagePart, $language, $context);
165
            }
166
        }
167
    }
168
169
    /**
170
     * @param mixed(Node|string) $nodeOrInternalName
171
     * @param string             $language
172
     * @param string             $templateName
173
     */
174
    public function setPageTemplate($nodeOrInternalName, $language, $templateName)
175
    {
176
        $node = $this->getNode($nodeOrInternalName);
177
        /** @var $translation NodeTranslation */
178
        $translation = $node->getNodeTranslation($language, true);
179
        /** @var HasPageTemplateInterface|EntityInterface $page */
180
        $page = $translation->getRef($this->em);
181
182
        /** @var PageTemplateConfigurationRepository $repo */
183
        $repo = $this->em->getRepository(PageTemplateConfiguration::class);
184
        $pageTemplateConfiguration = $repo->findFor($page);
185
        if ($pageTemplateConfiguration) {
186
            $pageTemplateConfiguration->setPageTemplate($templateName);
187
        } else {
188
            $pageTemplateConfiguration = new PageTemplateConfiguration();
189
            $pageTemplateConfiguration->setPageId($page->getId());
190
            $pageTemplateConfiguration->setPageEntityName(ClassLookup::getClass($page));
191
            $pageTemplateConfiguration->setPageTemplate($templateName);
192
        }
193
194
        $this->em->persist($pageTemplateConfiguration);
195
        $this->em->flush();
196
    }
197
198
    /**
199
     * A helper function to express what pagepart you want.
200
     *
201
     * It just accepts a classname and an array of setter functions with their requested values.
202
     *
203
     * It'll return an anonymous function which instantiates the pagepart.
204
     *
205
     * @param string $pagePartClassName the full class name of the pagepart you want to instantiate
206
     * @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 @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive. In addition it looks for parameters that have the generic type array and suggests a stricter type like array<String>.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
207
     *
208
     * @return callable the function that will instantiate a pagepart
209
     */
210
    public function getCreatorArgumentsForPagePartAndProperties($pagePartClassName, array $setters = null)
211
    {
212
        return function () use ($pagePartClassName, $setters) {
213
            $pp = new $pagePartClassName();
214
215
            if (!\is_null($setters)) {
216
                foreach ($setters as $setter => $value) {
217
                    \call_user_func(array($pp, $setter), $value);
218
                }
219
            }
220
221
            return $pp;
222
        };
223
    }
224
225
    /**
226
     * @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...
227
     *
228
     * @return object
229
     */
230
    private function getNode($nodeOrInternalName)
231
    {
232
        if (\is_string($nodeOrInternalName)) {
233
            return $this->nodeRepo->findOneBy(array('internalName' => $nodeOrInternalName));
234
        }
235
236
        return $nodeOrInternalName;
237
    }
238
}
239