Issues (43)

Security Analysis    no request data  

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.

src/Data/MongoDb/MongoDbEntityConfig.php (4 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
 * File was created 11.02.2016 17:38
4
 */
5
6
namespace PeekAndPoke\Component\Slumber\Data\MongoDb;
7
8
use PeekAndPoke\Component\PropertyAccess\PropertyAccess;
9
use PeekAndPoke\Component\Psi\Psi;
10
use PeekAndPoke\Component\Slumber\Annotation\ClassMarker;
11
use PeekAndPoke\Component\Slumber\Annotation\ClassPostDeleteListenerMarker;
12
use PeekAndPoke\Component\Slumber\Annotation\ClassPostSaveListenerMarker;
13
use PeekAndPoke\Component\Slumber\Annotation\CompoundIndexDefinition;
14
use PeekAndPoke\Component\Slumber\Annotation\PropertyPreSaveVisitorMarker;
15
use PeekAndPoke\Component\Slumber\Annotation\PropertyStorageIndexMarker;
16
use PeekAndPoke\Component\Slumber\Annotation\Slumber\AsObject;
17
use PeekAndPoke\Component\Slumber\Annotation\Slumber\Store\AsDbReference;
18
use PeekAndPoke\Component\Slumber\Annotation\Slumber\Store\AsId;
19
use PeekAndPoke\Component\Slumber\Core\Codec\Property\CollectionMapper;
20
use PeekAndPoke\Component\Slumber\Core\Codec\Property\ObjectMapper;
21
use PeekAndPoke\Component\Slumber\Core\LookUp\EntityConfig;
22
use PeekAndPoke\Component\Slumber\Core\LookUp\PropertyMarkedForSlumber;
23
use PeekAndPoke\Component\Slumber\Data\LazyDbReferenceCollection;
24
use PeekAndPoke\Component\Slumber\Data\LookUp\PropertyMarkedForIndexing;
25
use PeekAndPoke\Component\Slumber\Data\LookUp\PropertyMarkedForPreSaveVisit;
26
use PeekAndPoke\Component\Slumber\Data\MongoDb\Types\DbReferenceCollectionMapper;
27
use PeekAndPoke\Component\Slumber\Data\MongoDb\Types\DbReferenceMapper;
28
use PeekAndPoke\Component\Slumber\Data\MongoDb\Types\PrimaryIdMapper;
29
30
/**
31
 * @author Karsten J. Gerber <[email protected]>
32
 */
33
class MongoDbEntityConfig extends EntityConfig
34
{
35
    /** @var PropertyMarkedForSlumber */
36
    protected $idMarker;
37
38
    /** @var array|PropertyMarkedForPreSaveVisit[] */
39
    protected $preSaveVisits = [];
40
41
    /** @var array|ClassPostSaveListenerMarker[] */
42
    protected $postSaveClassListeners = [];
43
    /** @var array|ClassPostDeleteListenerMarker[] */
44
    protected $postDeleteClassListeners = [];
45
46
    /** @var array|PropertyMarkedForIndexing[] */
47
    protected $indexedProperties = [];
48
    /** @var array|CompoundIndexDefinition[] */
49
    protected $compoundIndexes = [];
50
51
    /**
52
     * @param EntityConfig $config
53
     *
54
     * @return MongoDbEntityConfig
55
     */
56 2
    public static function from(EntityConfig $config)
57
    {
58 2
        $result = new self(
59 2
            $config->getClassName(),
60 2
            $config->getCreator(),
61 2
            $config->getMarkersOnClass(),
62 2
            $config->getMarkedProperties()
63
        );
64
65 2
        $result->initialize();
66
67 2
        return $result;
68
    }
69
70
    /**
71
     * Get access to the primary id in order to read and write it without having to know the name of the property
72
     *
73
     * @return PropertyAccess
74
     */
75 26
    public function getIdAccess()
76
    {
77 26
        return $this->idMarker->propertyAccess;
78
    }
79
80
    /**
81
     * @return CompoundIndexDefinition[]
82
     */
83
    public function getCompoundIndexes()
84
    {
85
        return $this->compoundIndexes;
86
    }
87
88
    /**
89
     * @return PropertyMarkedForIndexing[]
90
     */
91
    public function getIndexedProperties()
92
    {
93
        return $this->indexedProperties;
94
    }
95
96
    /**
97
     * @return PropertyMarkedForPreSaveVisit[]
98
     */
99 28
    public function getPreSaveVisits()
100
    {
101 28
        return $this->preSaveVisits;
102
    }
103
104
    /**
105
     * @return bool
106
     */
107 26
    public function hasPostSaveClassListeners()
108
    {
109 26
        return \count($this->postSaveClassListeners) > 0;
110
    }
111
112
    /**
113
     * @return ClassPostSaveListenerMarker[]
114
     */
115 4
    public function getPostSaveClassListeners()
116
    {
117 4
        return $this->postSaveClassListeners;
118
    }
119
120
    /**
121
     * @return bool
122
     */
123
    public function hasPostDeleteClassListeners()
124
    {
125
        return \count($this->postDeleteClassListeners) > 0;
126
    }
127
128
    /**
129
     * @return ClassPostDeleteListenerMarker[]
130
     */
131
    public function getPostDeleteClassListeners()
132
    {
133
        return $this->postDeleteClassListeners;
134
    }
135
136 2
    private function initialize()
137
    {
138
        // setup and modify the id-marker
139 2
        $this->setUpIdMarker();
140
141
        // setup and modify markers with database-relations
142 2
        $this->setUpDbReferenceMarkers();
143
144
        // setup property live-cycle event listeners
145 2
        $this->setUpPreSaveVisits();
146
147
        // setup class live-cycle event listeners
148 2
        $this->setUpPostSaveClassListeners();
149 2
        $this->setUpPostDeleteClassListeners();
150
151
        // setup indexes
152 2
        $this->setUpIndexedProperties();
153 2
        $this->setUpCompoundIndexes();
154 2
    }
155
156 2
    private function setUpIdMarker()
157
    {
158
        // we modify the property markers if we find an AsId::class
159
160 2
        $this->markedProperties = Psi::it($this->getMarkedProperties())
161 2
            ->filter(new Psi\IsInstanceOf(PropertyMarkedForSlumber::class))
162 2
            ->map(function (PropertyMarkedForSlumber $p) {
163
164
                // search for the first AsId marker and modify it
165 2
                if ($this->idMarker === null && $p->getFirstMarkerOf(AsId::class)) {
166
                    // remember the property marked as primary id
167
                    return $this->idMarker = $p->withAlias('_id')->withMapper(new PrimaryIdMapper($p->mapper->getOptions()));
168
                }
169
170
                // return unmodified
171 2
                return $p;
172 2
            })
173 2
            ->toArray();
174 2
    }
175
176 2
    private function setUpDbReferenceMarkers()
177
    {
178 2
        $this->markedProperties = Psi::it($this->getMarkedProperties())
179 2
            ->filter(new Psi\IsInstanceOf(PropertyMarkedForSlumber::class))
180 2
            ->map(function (PropertyMarkedForSlumber $p) {
181
182
                /** @var AsDbReference $asDbRef */
183 2
                $asDbRef = $p->getFirstMarkerOf(AsDbReference::class);
184
185
                // do we have a AsDbReference marker ?
186 2
                if ($asDbRef) {
187
188
                    // is it accompanied by an AsObject marker ?
189
                    /** @var AsObject $asObj */
190
                    $asObj = $p->getFirstMarkerOf(AsObject::class);
191
192
                    if ($asObj) {
193
                        // we need the actual object
194
                        $asDbRef->setObjectOptions($asObj);
195
196
                        // return the modified marker
197
                        return $p->withMapper(new DbReferenceMapper($asDbRef));
198
                    }
199
200
                    // is it a collection and has an ObjectMapper as leave? Then we replace t
201
                    if ($p->mapper instanceof CollectionMapper && $p->mapper->isLeaveOfType(ObjectMapper::class)) {
202
203
                        /** @var ObjectMapper $leaf */
204
                        $leaf = $p->mapper->getLeaf();
205
                        // set the options of the referenced object
206
                        $asDbRef->setObjectOptions($leaf->getOptions());
207
                        // replace the leave mapper
208
                        $p->mapper->setLeaf(new DbReferenceMapper($asDbRef));
209
210
                        // we must also wrap the out collection so that we can un-wrap the LazyDbReferences
211
                        if ($asDbRef->lazy) {
212
                            $p->mapper->setLeafParentsCollectionType(LazyDbReferenceCollection::class);
213
                        }
214
215
                        // when the collection only has one child (Any Slumber\As...) we have to replace the mapper itself
216
                        if ($p->mapper->getNestingLevel() === 1) {
217
                            /** @noinspection PhpParamsInspection */
218
                            $p->mapper = new DbReferenceCollectionMapper($p->mapper);
219
                        }
220
                        // else {
221
                        // TODO: to be implemented . We need to replace the mapper of the leafs grand-parent, just like above
222
                        //       it works without it but has a high performance impact
223
                        // }
224
225
                        return $p;
226
                    }
227
                }
228
229
                // return un-modified
230 2
                return $p;
231 2
            })
232 2
            ->toArray();
233 2
    }
234
235 2 View Code Duplication
    private function setUpPreSaveVisits()
0 ignored issues
show
This method seems to be duplicated in 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...
236
    {
237
        // set up the pre save property visits
238 2
        $this->preSaveVisits = array_merge(
239 2
            $this->preSaveVisits,
240 2
            Psi::it($this->getMarkedProperties())
241 2
                ->filter(new Psi\IsInstanceOf(PropertyMarkedForSlumber::class))
242 2
                ->filter(function (PropertyMarkedForSlumber $p) {
243 2
                    return $p->getFirstMarkerOf(PropertyPreSaveVisitorMarker::class) !== null;
244 2
                })
245 2
                ->map(function (PropertyMarkedForSlumber $p) {
246
                    $res               = new PropertyMarkedForPreSaveVisit();
247
                    $res->propertyName = $p->name;
248
                    $res->markers      = $p->getMarkersOf(PropertyPreSaveVisitorMarker::class);
0 ignored issues
show
Documentation Bug introduced by
It seems like $p->getMarkersOf(\PeekAn...veVisitorMarker::class) of type array<integer,object<Pee...tation\PropertyMarker>> is incompatible with the declared type array<integer,object<Pee...yPreSaveVisitorMarker>> of property $markers.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
249
250
                    return $res;
251 2
                })
252 2
                ->toArray()
253
        );
254 2
    }
255
256 2
    private function setUpPostSaveClassListeners()
257
    {
258 2
        $this->postSaveClassListeners = array_merge(
259 2
            $this->postSaveClassListeners,
260 2
            Psi::it($this->getMarkersOnClass())
261 2
                ->filter(new Psi\IsInstanceOf(ClassPostSaveListenerMarker::class))
262 2
                ->toArray()
263
        );
264 2
    }
265
266 2
    private function setUpPostDeleteClassListeners()
267
    {
268 2
        $this->postDeleteClassListeners = array_merge(
269 2
            $this->postDeleteClassListeners,
270 2
            Psi::it($this->getMarkersOnClass())
271 2
                ->filter(new Psi\IsInstanceOf(ClassPostDeleteListenerMarker::class))
272 2
                ->toArray()
273
        );
274 2
    }
275
276 2 View Code Duplication
    private function setUpIndexedProperties()
0 ignored issues
show
This method seems to be duplicated in 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...
277
    {
278
        // get indexed properties
279
        // TODO: write tests
280 2
        $this->indexedProperties = array_merge(
281 2
            $this->indexedProperties,
282 2
            Psi::it($this->getMarkedProperties())
283 2
                ->filter(new Psi\IsInstanceOf(PropertyMarkedForSlumber::class))
284 2
                ->filter(function (PropertyMarkedForSlumber $p) {
285 2
                    return $p->getFirstMarkerOf(PropertyStorageIndexMarker::class) !== null;
286 2
                })
287 2
                ->map(function (PropertyMarkedForSlumber $p) {
288
                    $res               = new PropertyMarkedForIndexing();
289
                    $res->propertyName = $p->name;
290
                    $res->markers      = $p->getMarkersOf(PropertyStorageIndexMarker::class);
0 ignored issues
show
Documentation Bug introduced by
It seems like $p->getMarkersOf(\PeekAn...rageIndexMarker::class) of type array<integer,object<Pee...tation\PropertyMarker>> is incompatible with the declared type array<integer,object<Pee...rtyStorageIndexMarker>> of property $markers.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
291
292
                    return $res;
293 2
                })
294 2
                ->toArray()
295
        );
296 2
    }
297
298 2
    private function setUpCompoundIndexes()
299
    {
300
        // get compound indexes
301
        // TODO: write tests
302 2
        $this->compoundIndexes = array_merge(
303 2
            $this->compoundIndexes,
304 2
            Psi::it($this->getMarkersOnClass())
305 2
                ->filter(new Psi\IsInstanceOf(ClassMarker::class))
306 2
                ->filter(new Psi\IsInstanceOf(CompoundIndexDefinition::class))
307 2
                ->toArray()
308
        );
309 2
    }
310
}
311