Passed
Push — master ( 6588d8...6bef90 )
by Alex
01:21
created

ProvidersWrapper::getResourceProperties()   C

Complexity

Conditions 7
Paths 3

Size

Total Lines 32
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 32
rs 6.7272
cc 7
eloc 17
nc 3
nop 2
1
<?php
2
3
namespace POData\Providers;
4
5
use POData\Common\InvalidOperationException;
6
use POData\Common\Messages;
7
use POData\Common\ODataException;
8
use POData\Configuration\IServiceConfiguration;
9
use POData\Providers\Expression\IExpressionProvider;
10
use POData\Providers\Metadata\EdmSchemaVersion;
11
use POData\Providers\Metadata\IMetadataProvider;
12
use POData\Providers\Metadata\ResourceAssociationSet;
13
use POData\Providers\Metadata\ResourceEntityType;
14
use POData\Providers\Metadata\ResourceProperty;
15
use POData\Providers\Metadata\ResourceSet;
16
use POData\Providers\Metadata\ResourceSetWrapper;
17
use POData\Providers\Metadata\ResourceType;
18
use POData\Providers\Metadata\ResourceTypeKind;
19
use POData\Providers\Query\IQueryProvider;
20
use POData\Providers\Query\QueryResult;
21
use POData\Providers\Query\QueryType;
22
use POData\UriProcessor\QueryProcessor\ExpressionParser\FilterInfo;
23
use POData\UriProcessor\QueryProcessor\OrderByParser\InternalOrderByInfo;
24
use POData\UriProcessor\QueryProcessor\SkipTokenParser\InternalSkipTokenInfo;
25
use POData\UriProcessor\QueryProcessor\SkipTokenParser\SkipTokenInfo;
26
use POData\UriProcessor\ResourcePathProcessor\SegmentParser\KeyDescriptor;
27
28
/**
29
 * Class ProvidersWrapper.
30
 *
31
 * A wrapper class over IMetadataProvider and IQueryProvider implementations, All calls to implementation of methods
32
 * of these interfaces should go through this wrapper class so that wrapper methods of this class can perform validation
33
 */
34
class ProvidersWrapper
35
{
36
    /**
37
     * Holds reference to IMetadataProvider implementation.
38
     *
39
     * @var IMetadataProvider
40
     */
41
    private $metaProvider;
42
43
    /**
44
     * Holds reference to IServiceConfiguration implementation.
45
     *
46
     * @var IServiceConfiguration
47
     */
48
    private $config;
49
50
    /*
51
     * Holds reference to ProvidersQueryWrapper implementation
52
     *
53
     * @var ProvidersQueryWrapper
54
     */
55
    private $providerWrapper;
56
57
    /**
58
     * Cache for ResourceProperties of a resource type that belongs to a
59
     * resource set. An entry (ResourceProperty collection) in this cache
60
     * contains only the visible properties of ResourceType.
61
     *
62
     * @var array<array>
63
     */
64
    private $propertyCache;
65
66
    /**
67
     * Cache for ResourceSetWrappers. If ResourceSet is invisible value will
68
     * be null.
69
     *
70
     * @var ResourceSetWrapper[] indexed by resource set name
71
     */
72
    private $setWrapperCache;
73
74
    /**
75
     * Cache for ResourceTypes.
76
     *
77
     * @var ResourceType[] indexed by resource type name
78
     */
79
    private $typeCache;
80
81
    /**
82
     * Cache for ResourceAssociationSet. If ResourceAssociationSet is invisible
83
     * value will be null.
84
     *
85
     * @var ResourceAssociationSet[] indexed by name
86
     */
87
    private $associationSetCache;
0 ignored issues
show
Unused Code introduced by
The property $associationSetCache is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
88
89
    /**
90
     * Creates a new instance of ProvidersWrapper.
91
     *
92
     * @param IMetadataProvider     $meta   Reference to IMetadataProvider implementation
93
     * @param IQueryProvider        $query  Reference to IQueryProvider implementation
94
     * @param IServiceConfiguration $config Reference to IServiceConfiguration implementation
95
     */
96
    public function __construct(IMetadataProvider $meta, IQueryProvider $query, IServiceConfiguration $config)
97
    {
98
        $this->metaProvider = $meta;
99
        $this->config = $config;
100
        $this->providerWrapper = new ProvidersQueryWrapper($query);
101
        $this->setWrapperCache = [];
102
        $this->typeCache = [];
103
        $this->propertyCache = [];
104
    }
105
106
    public function getProviderWrapper()
107
    {
108
        assert(null != $this->providerWrapper, 'Provider wrapper must be set');
109
        return $this->providerWrapper;
110
    }
111
112
    //Wrappers for IMetadataProvider methods
113
114
    /**
115
     * To get the Container name for the data source,
116
     * Note: Wrapper for IMetadataProvider::getContainerName method
117
     * implementation.
118
     *
119
     * @throws ODataException Exception if implementation returns empty container name
120
     *
121
     * @return string that contains the name of the container
122
     */
123
    public function getContainerName()
124
    {
125
        $containerName = $this->metaProvider->getContainerName();
126
        if (empty($containerName)) {
127
            throw new ODataException(
128
                Messages::providersWrapperContainerNameMustNotBeNullOrEmpty(),
129
                500
130
            );
131
        }
132
133
        return $containerName;
134
    }
135
136
    /**
137
     * To get Namespace name for the data source,
138
     * Note: Wrapper for IMetadataProvider::getContainerNamespace method implementation.
139
     *
140
     * @throws ODataException Exception if implementation returns empty container namespace
141
     *
142
     * @return string that contains the namespace name
143
     */
144
    public function getContainerNamespace()
145
    {
146
        $containerNamespace = $this->metaProvider->getContainerNamespace();
147
        if (empty($containerNamespace)) {
148
            throw new ODataException(
149
                Messages::providersWrapperContainerNamespaceMustNotBeNullOrEmpty(),
150
                500
151
            );
152
        }
153
154
        return $containerNamespace;
155
    }
156
157
    /**
158
     * To get the data service configuration.
159
     *
160
     * @return IServiceConfiguration
161
     */
162
    public function getConfiguration()
163
    {
164
        return $this->config;
165
    }
166
167
    /**
168
     *  To get all entity set information,
169
     *  Note: Wrapper for IMetadataProvider::getResourceSets method implementation,
170
     *  This method returns array of ResourceSetWrapper instances but the corresponding IDSMP method
171
     *  returns array of ResourceSet instances.
172
     *
173
     *  @throws ODataException when two resource sets with the same name are encountered
174
     *
175
     *  @return ResourceSetWrapper[] The ResourceSetWrappers for the visible ResourceSets
176
     */
177
    public function getResourceSets()
178
    {
179
        $resourceSets = $this->metaProvider->getResourceSets();
180
        $resourceSetWrappers = [];
181
        $resourceSetNames = [];
182
        foreach ($resourceSets as $resourceSet) {
183
            $name = $resourceSet->getName();
184
            if (in_array($name, $resourceSetNames)) {
185
                throw new ODataException(Messages::providersWrapperEntitySetNameShouldBeUnique($name), 500);
186
            }
187
188
            $resourceSetNames[] = $name;
189
            $resourceSetWrapper = $this->validateResourceSetAndGetWrapper($resourceSet);
190
            if (null !== $resourceSetWrapper) {
191
                $resourceSetWrappers[] = $resourceSetWrapper;
192
            }
193
        }
194
195
        return $resourceSetWrappers;
196
    }
197
198
    /**
199
     * This function perform the following operations
200
     *  (1) If the cache contain an entry [key, value] for the resourceset then
201
     *      return the entry-value
202
     *  (2) If the cache not contain an entry for the resourceset then validate
203
     *      the resourceset
204
     *            (a) If valid add entry as [resouceset_name, resourceSetWrapper]
205
     *            (b) if not valid add entry as [resouceset_name, null]
206
     *  Note: validating a resourceset means checking the resourceset is visible
207
     *  or not using configuration.
208
     *
209
     * @param ResourceSet $resourceSet The resourceset to validate and get the
210
     *                                 wrapper for
211
     *
212
     * @return ResourceSetWrapper|null Returns an instance if a resource set with the given name is visible
213
     */
214
    private function validateResourceSetAndWrapper(ResourceSet $resourceSet)
215
    {
216
        $cacheKey = $resourceSet->getName();
217
        if (array_key_exists($cacheKey, $this->setWrapperCache)) {
218
            return $this->setWrapperCache[$cacheKey];
219
        }
220
221
        $this->validateResourceType($resourceSet->getResourceType());
222
        $wrapper = new ResourceSetWrapper($resourceSet, $this->config);
223
        $nuVal = $wrapper->isVisible() ? $wrapper : null;
224
        $this->setWrapperCache[$cacheKey] = $nuVal;
225
226
        return $this->setWrapperCache[$cacheKey];
227
    }
228
229
    /**
230
     * Validates the given instance of ResourceType.
231
     *
232
     * @param ResourceType $resourceType The ResourceType to validate
233
     *
234
     * @throws ODataException Exception if $resourceType is invalid
235
     *
236
     * @return ResourceType
237
     */
238
    private function validateResourceType(ResourceType $resourceType)
239
    {
240
        $cacheKey = $resourceType->getName();
241
        if (array_key_exists($cacheKey, $this->typeCache)) {
242
            return $this->typeCache[$cacheKey];
243
        }
244
245
        //TODO: Do validation if any for the ResourceType
0 ignored issues
show
Coding Style Best Practice introduced by
Comments for TODO tasks are often forgotten in the code; it might be better to use a dedicated issue tracker.
Loading history...
246
        $this->typeCache[$cacheKey] = $resourceType;
247
248
        return $resourceType;
249
    }
250
251
    /**
252
     * To get all resource types in the data source,
253
     * Note: Wrapper for IMetadataProvider::getTypes method implementation.
254
     *
255
     * @throws ODataException
256
     * @return ResourceType[]
257
     */
258
    public function getTypes()
259
    {
260
        $resourceTypes = $this->metaProvider->getTypes();
261
        $resourceTypeNames = [];
262
        foreach ($resourceTypes as $resourceType) {
263
            if (in_array($resourceType->getName(), $resourceTypeNames)) {
264
                throw new ODataException(
265
                    Messages::providersWrapperEntityTypeNameShouldBeUnique($resourceType->getName()),
266
                    500
267
                );
268
            }
269
270
            $resourceTypeNames[] = $resourceType->getName();
271
            $this->validateResourceType($resourceType);
272
        }
273
274
        return $resourceTypes;
275
    }
276
277
    public function getSingletons()
278
    {
279
        $singletons = $this->metaProvider->getSingletons();
280
        return (null == $singletons) ? [] : $singletons;
281
    }
282
283
    /**
284
     * To get a resource set based on the specified resource set name which is
285
     * visible,
286
     * Note: Wrapper for IMetadataProvider::resolveResourceSet method
287
     * implementation.
288
     *
289
     * @param string $name Name of the resource set
290
     *
291
     * @return ResourceSetWrapper|null Returns resource set with the given name if found,
292
     *                                 NULL if resource set is set to invisible or not found
293
     */
294
    public function resolveResourceSet($name)
295
    {
296
        if (array_key_exists($name, $this->setWrapperCache)) {
297
            return $this->setWrapperCache[$name];
298
        }
299
300
        $resourceSet = $this->metaProvider->resolveResourceSet($name);
301
        if (null === $resourceSet) {
302
            return null;
303
        }
304
305
        return $this->validateResourceSetAndWrapper($resourceSet);
306
    }
307
308
    /**
309
     * To get a resource type based on the resource set name,
310
     * Note: Wrapper for IMetadataProvider::resolveResourceType
311
     * method implementation.
312
     *
313
     * @param string $name Name of the resource set
314
     *
315
     * @throws ODataException If the ResourceType is invalid
316
     *
317
     * @return ResourceType|null resource type with the given resource set name if found else NULL
318
     */
319
    public function resolveResourceType($name)
320
    {
321
        $resourceType = $this->metaProvider->resolveResourceType($name);
322
        if (null === $resourceType) {
323
            return null;
324
        }
325
326
        return $this->validateResourceType($resourceType);
327
    }
328
329
    /**
330
     * Try to resolve named singleton
331
     *
332
     * @param string $name
333
     * @return mixed|null
334
     */
335
    public function resolveSingleton($name)
336
    {
337
        $singletons = $this->metaProvider->getSingletons();
338
        if (array_key_exists($name, $singletons)) {
339
            return $singletons[$name];
340
        }
341
        return null;
342
    }
343
344
    /**
345
     * The method must return a collection of all the types derived from
346
     * $resourceType The collection returned should NOT include the type
347
     * passed in as a parameter
348
     * Note: Wrapper for IMetadataProvider::getDerivedTypes
349
     * method implementation.
350
     *
351
     * @param ResourceEntityType $resourceType Resource to get derived resource types from
352
     *
353
     * @throws InvalidOperationException when the meat provider doesn't return an array
354
     *
355
     * @return ResourceType[]
356
     */
357
    public function getDerivedTypes(ResourceEntityType $resourceType)
358
    {
359
        $derivedTypes = $this->metaProvider->getDerivedTypes($resourceType);
360
        if (!is_array($derivedTypes)) {
361
            throw new InvalidOperationException(
362
                Messages::metadataAssociationTypeSetInvalidGetDerivedTypesReturnType($resourceType->getName())
363
            );
364
        }
365
366
        foreach ($derivedTypes as $derivedType) {
367
            $this->validateResourceType($derivedType);
368
        }
369
370
        return $derivedTypes;
371
    }
372
373
    /**
374
     * Returns true if $resourceType represents an Entity Type which has derived
375
     * Entity Types, else false.
376
     * Note: Wrapper for IMetadataProvider::hasDerivedTypes method implementation.
377
     *
378
     * @param ResourceEntityType    $resourceType   Resource to check for derived resource types
379
     *
380
     * @throws ODataException If the ResourceType is invalid
381
     *
382
     * @return bool
383
     */
384
    public function hasDerivedTypes(ResourceEntityType $resourceType)
385
    {
386
        $this->validateResourceType($resourceType);
387
388
        return $this->metaProvider->hasDerivedTypes($resourceType);
389
    }
390
391
    /**
392
     * Gets the visible resource properties for the given resource type from the given resource set wrapper.
393
     *
394
     * @param ResourceSetWrapper $setWrapper   Resource set wrapper in question
395
     * @param ResourceType       $resourceType Resource type in question
396
     *
397
     * @return ResourceProperty[] Collection of visible resource properties from the given resource set wrapper
398
     *                            and resource type
399
     */
400
    public function getResourceProperties(ResourceSetWrapper $setWrapper, ResourceType $resourceType)
401
    {
402
        if ($resourceType->getResourceTypeKind() != ResourceTypeKind::ENTITY()) {
403
            //Complex resource type
404
            return $resourceType->getAllProperties();
405
        }
406
        //TODO: move this to doctrine annotations
0 ignored issues
show
Coding Style Best Practice introduced by
Comments for TODO tasks are often forgotten in the code; it might be better to use a dedicated issue tracker.
Loading history...
407
        $cacheKey = $setWrapper->getName() . '_' . $resourceType->getFullName();
408
        if (!array_key_exists($cacheKey, $this->propertyCache)) {
409
            //Fill the cache
410
            $this->propertyCache[$cacheKey] = [];
411
            foreach ($resourceType->getAllProperties() as $resourceProperty) {
412
                //Check whether this is a visible navigation property
413
                //TODO: is this broken?? see #87
0 ignored issues
show
Coding Style Best Practice introduced by
Comments for TODO tasks are often forgotten in the code; it might be better to use a dedicated issue tracker.
Loading history...
414
                if ($resourceProperty->getTypeKind() == ResourceTypeKind::ENTITY()
415
                    && $resourceType instanceof ResourceEntityType
416
                    && null !== $this->getResourceSetWrapperForNavigationProperty(
417
                        $setWrapper,
418
                        $resourceType,
419
                        $resourceProperty
420
                    )
421
                ) {
422
                    $this->propertyCache[$cacheKey][$resourceProperty->getName()] = $resourceProperty;
423
                } else {
424
                    //primitive, bag or complex property
425
                    $this->propertyCache[$cacheKey][$resourceProperty->getName()] = $resourceProperty;
426
                }
427
            }
428
        }
429
430
        return $this->propertyCache[$cacheKey];
431
    }
432
433
    /**
434
     * Gets the target resource set wrapper for the given navigation property,
435
     * source resource set wrapper and the source resource type.
436
     *
437
     * @param ResourceSetWrapper $resourceSetWrapper         Source resource set
438
     * @param ResourceEntityType $resourceType               Source resource type
439
     * @param ResourceProperty   $navigationResourceProperty Navigation property
440
     *
441
     * @return ResourceSetWrapper|null Returns instance of ResourceSetWrapper
442
     *                                 (describes the entity set and associated configuration) for the
443
     *                                 given navigation property. returns NULL if resourceset for the
444
     *                                 navigation property is invisible or if metadata provider returns
445
     *                                 null resource association set
446
     */
447
    public function getResourceSetWrapperForNavigationProperty(
448
        ResourceSetWrapper $resourceSetWrapper,
449
        ResourceEntityType $resourceType,
450
        ResourceProperty $navigationResourceProperty
451
    ) {
452
        $associationSet = $this->getResourceAssociationSet(
453
            $resourceSetWrapper,
454
            $resourceType,
455
            $navigationResourceProperty
456
        );
457
458
        if (null !== $associationSet) {
459
            $relatedAssociationSetEnd = $associationSet->getRelatedResourceAssociationSetEnd(
460
                $resourceSetWrapper->getResourceSet(),
461
                $resourceType,
462
                $navigationResourceProperty
463
            );
464
465
            return $this->validateResourceSetAndWrapper(
466
                $relatedAssociationSetEnd->getResourceSet()
467
            );
468
        }
469
        return null;
470
    }
471
472
    /**
473
     * Gets the ResourceAssociationSet instance for the given source association end,
474
     * Note: Wrapper for IMetadataProvider::getResourceAssociationSet
475
     * method implementation.
476
     *
477
     * @param ResourceSet        $set      Resource set of the source association end
478
     * @param ResourceEntityType $type     Resource type of the source association end
479
     * @param ResourceProperty   $property Resource property of the source association end
480
     *
481
     * @throws ODataException
482
     * @return ResourceAssociationSet|null Returns ResourceAssociationSet for the source
483
     *                                     association end, NULL if no such
484
     *                                     association end or resource set in the
485
     *                                     other end of the association is invisible
486
     */
487
    public function getResourceAssociationSet(
488
        ResourceSet $set,
489
        ResourceEntityType $type,
490
        ResourceProperty $property
491
    ) {
492
        $type = $this->getResourceTypeWherePropertyIsDeclared($type, $property);
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $type. This often makes code more readable.
Loading history...
493
        // usage below requires $type to not be null - so kaboom as early as possible
494
        assert(null != $type, 'Resource type obtained from property must not be null.');
495
        assert($type instanceof ResourceEntityType);
496
497
        $associationSet = $this->metaProvider->getResourceAssociationSet(
498
            $set,
499
            $type,
500
            $property
501
        );
502
        assert(
503
            null == $associationSet || $associationSet instanceof ResourceAssociationSet,
504
            'Retrieved resource association must be either null or an instance of ResourceAssociationSet'
505
        );
506
507
        if (null !== $associationSet) {
508
            $thisAssociationSetEnd = $associationSet->getResourceAssociationSetEnd(
509
                $set,
510
                $type,
511
                $property
512
            );
513
514
            $relatedAssociationSetEnd = $associationSet->getRelatedResourceAssociationSetEnd(
515
                $set,
516
                $type,
517
                $property
518
            );
519
520
            //If either $thisAssociationSetEnd and/or $relatedAssociationSetEnd
0 ignored issues
show
Unused Code Comprehensibility introduced by
46% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
521
            //is null means the associationset we got from the IDSMP::getResourceAssociationSet is invalid.
522
523
            //Return null, if either AssociationSet's End1 or End2's resourceset name
524
            //doesn't match the name of resource set wrapper (param1) and resource type is not assignable
525
            //from given resource type (param2)
526
            if (null === $thisAssociationSetEnd || null === $relatedAssociationSetEnd) {
527
                throw new ODataException(
528
                    Messages::providersWrapperIDSMPGetResourceSetReturnsInvalidResourceSet(
529
                        $set->getName(),
530
                        $type->getFullName(),
531
                        $property->getName()
532
                    ),
533
                    500
534
                );
535
            }
536
537
            $relatedResourceSetWrapper = $this->validateResourceSetAndWrapper(
538
                $relatedAssociationSetEnd->getResourceSet()
539
            );
540
            if ($relatedResourceSetWrapper === null) {
541
                $associationSet = null;
542
            } else {
543
                $this->validateResourceType($thisAssociationSetEnd->getResourceType());
544
                $this->validateResourceType($relatedAssociationSetEnd->getResourceType());
545
            }
546
        }
547
        assert(
548
            null == $associationSet || $associationSet instanceof ResourceAssociationSet,
549
            'Retrieved resource assocation must be either null or an instance of ResourceAssociationSet'
550
        );
551
552
        return $associationSet;
553
    }
554
555
    /**
556
     * Gets the resource type on which the resource property is declared on,
557
     * If property is not declared in the given resource type, then this
558
     * function drill down to the inheritance hierarchy of the given resource
559
     * type to find out the base class in which the property is declared.
560
     *
561
     * @param ResourceType     $type     The resource type to start looking
562
     * @param ResourceProperty $property The resource property in question
563
     *
564
     * @return ResourceType|null Returns reference to the ResourceType on which
565
     *                           the $property is declared, NULL if
566
     *                           $property is not declared anywhere
567
     *                           in the inheritance hierarchy
568
     */
569
    private function getResourceTypeWherePropertyIsDeclared(ResourceType $type, ResourceProperty $property)
570
    {
571
        while (null !== $type) {
572
            if (null !== $type->resolvePropertyDeclaredOnThisType($property->getName())) {
573
                break;
574
            }
575
576
            $type = $type->getBaseType();
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $type. This often makes code more readable.
Loading history...
577
        }
578
579
        return $type;
580
    }
581
582
    /**
583
     * Wrapper function over _validateResourceSetAndGetWrapper function.
584
     *
585
     * @param ResourceSet $resourceSet see the comments of _validateResourceSetAndGetWrapper
586
     *
587
     * @return ResourceSetWrapper|null see the comments of _validateResourceSetAndGetWrapper
588
     */
589
    public function validateResourceSetAndGetWrapper(ResourceSet $resourceSet)
590
    {
591
        return $this->validateResourceSetAndWrapper($resourceSet);
592
    }
593
594
    /**
595
     * Gets the Edm Schema version compliance to the metadata.
596
     *
597
     * @return EdmSchemaVersion
598
     */
599
    public function getEdmSchemaVersion()
600
    {
601
        //The minimal schema version for custom provider is 1.1
602
        return EdmSchemaVersion::VERSION_1_DOT_1;
603
    }
604
605
    /**
606
     * Gets the underlying custom expression provider, the end developer is
607
     * responsible for implementing IExpressionProvider if he choose for.
608
     *
609
     * @return IExpressionProvider Instance of IExpressionProvider implementation
610
     */
611
    public function getExpressionProvider()
612
    {
613
        return $this->getProviderWrapper()->getExpressionProvider();
614
    }
615
616
    /**
617
     * Indicates if the QueryProvider can handle ordered paging, this means respecting order, skip, and top parameters
618
     * If the query provider can not handle ordered paging, it must return the entire result set and POData will
619
     * perform the ordering and paging.
620
     *
621
     * @return bool True if the query provider can handle ordered paging, false if POData should perform the paging
622
     */
623
    public function handlesOrderedPaging()
0 ignored issues
show
Coding Style introduced by
function handlesOrderedPaging() does not seem to conform to the naming convention (^(?:is|has|should|may|supports)).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
624
    {
625
        return $this->getProviderWrapper()->handlesOrderedPaging();
626
    }
627
628
    /**
629
     * Gets collection of entities belongs to an entity set.
630
     *
631
     * @param QueryType                 $queryType   Indicates if this is a query for a count, entities, or entities
632
     *                                               with a count
633
     * @param ResourceSet               $resourceSet The entity set containing the entities that need to be fetched
634
     * @param FilterInfo|null           $filterInfo  Represents the $filter parameter of the OData query.
635
     *                                               NULL if no $filter specified
636
     * @param InternalOrderByInfo|null  $orderBy     The orderBy information
637
     * @param integer|null              $top         The top count
638
     * @param integer|null              $skip        The skip count
639
     * @param SkipTokenInfo|null        $skipToken   The skip token
640
     *
641
     * @return QueryResult
642
     */
643
    public function getResourceSet(
644
        QueryType $queryType,
645
        ResourceSet $resourceSet,
646
        FilterInfo $filterInfo = null,
647
        InternalOrderByInfo $orderBy = null,
648
        $top = null,
649
        $skip = null,
650
        SkipTokenInfo $skipToken = null
651
    ) {
652
        return $this->getProviderWrapper()->getResourceSet(
653
            $queryType,
654
            $resourceSet,
655
            $filterInfo,
656
            $orderBy,
657
            $top,
658
            $skip,
659
            $skipToken
660
        );
661
    }
662
663
    /**
664
     * Gets an entity instance from an entity set identified by a key.
665
     *
666
     * @param ResourceSet   $resourceSet   The entity set containing the entity to fetch
667
     * @param KeyDescriptor $keyDescriptor The key identifying the entity to fetch
668
     *
669
     * @return object|null Returns entity instance if found, else null
670
     */
671
    public function getResourceFromResourceSet(ResourceSet $resourceSet, KeyDescriptor $keyDescriptor)
672
    {
673
        return $this->getProviderWrapper()->getResourceFromResourceSet($resourceSet, $keyDescriptor);
674
    }
675
676
    /**
677
     * Puts an entity instance to entity set identified by a key.
678
     *
679
     * @param ResourceSet   $resourceSet   The entity set containing the entity to update
680
     * @param KeyDescriptor $keyDescriptor The key identifying the entity to update
681
     * @param mixed         $data
682
     *
683
     * @return bool|null Returns result of executing query
684
     */
685
    public function putResource(
686
        ResourceSet $resourceSet,
687
        KeyDescriptor $keyDescriptor,
688
        $data
689
    ) {
690
        return $this->getProviderWrapper()->putResource(
691
            $resourceSet,
692
            $keyDescriptor,
693
            $data
694
        );
695
    }
696
697
    /**
698
     * Get related resource set for a resource.
699
     *
700
     * @param QueryType          $queryType         Indicates if this is a query for a count, entities, or entities
701
     *                                              with a count
702
     * @param ResourceSet        $sourceResourceSet The entity set containing the source entity
703
     * @param object             $sourceEntity      The source entity instance
704
     * @param ResourceSet        $targetResourceSet The resource set containing the target of the navigation property
705
     * @param ResourceProperty   $targetProperty    The navigation property to retrieve
706
     * @param FilterInfo|null    $filterInfo        Represents the $filter parameter of the OData query.
707
     *                                              NULL if no $filter specified
708
     * @param mixed              $orderBy           sorted order if we want to get the data in some specific order
709
     * @param int                $top               number of records which need to be retrieved
710
     * @param int                $skip              number of records which need to be skipped
711
     * @param SkipTokenInfo|null $skipToken         value indicating what records to skip
712
     *
713
     * @throws ODataException
714
     *
715
     * @return QueryResult
716
     */
717
    public function getRelatedResourceSet(
718
        QueryType $queryType,
719
        ResourceSet $sourceResourceSet,
720
        $sourceEntity,
721
        ResourceSet $targetResourceSet,
722
        ResourceProperty $targetProperty,
723
        $filterInfo,
724
        $orderBy,
725
        $top,
726
        $skip,
727
        SkipTokenInfo $skipToken = null
728
    ) {
729
        return $this->getProviderWrapper()->getRelatedResourceSet(
730
            $queryType,
731
            $sourceResourceSet,
732
            $sourceEntity,
733
            $targetResourceSet,
734
            $targetProperty,
735
            $filterInfo,
0 ignored issues
show
Bug introduced by
It seems like $filterInfo defined by parameter $filterInfo on line 723 can be null; however, POData\Providers\Provide...getRelatedResourceSet() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
736
            $orderBy,
737
            $top,
738
            $skip,
739
            $skipToken
740
        );
741
    }
742
743
    /**
744
     * Gets a related entity instance from an entity set identified by a key.
745
     *
746
     * @param ResourceSet      $sourceResourceSet The entity set related to the entity to be fetched
747
     * @param object           $sourceEntity      The related entity instance
748
     * @param ResourceSet      $targetResourceSet The entity set from which entity needs to be fetched
749
     * @param ResourceProperty $targetProperty    The metadata of the target property
750
     * @param KeyDescriptor    $keyDescriptor     The key to identify the entity to be fetched
751
     *
752
     * @return object|null Returns entity instance if found, else null
753
     */
754
    public function getResourceFromRelatedResourceSet(
755
        ResourceSet $sourceResourceSet,
756
        $sourceEntity,
757
        ResourceSet $targetResourceSet,
758
        ResourceProperty $targetProperty,
759
        KeyDescriptor $keyDescriptor
760
    ) {
761
        return $this->getProviderWrapper()->getResourceFromRelatedResourceSet(
762
            $sourceResourceSet,
763
            $sourceEntity,
764
            $targetResourceSet,
765
            $targetProperty,
766
            $keyDescriptor
767
        );
768
    }
769
770
    /**
771
     * Get related resource for a resource.
772
     *
773
     * @param ResourceSet      $sourceResourceSet The source resource set
774
     * @param object           $sourceEntity      The source resource
775
     * @param ResourceSet      $targetResourceSet The resource set of the navigation
776
     *                                            property
777
     * @param ResourceProperty $targetProperty    The navigation property to be
778
     *                                            retrieved
779
     *
780
     * @return object|null The related resource if exists, else null
781
     */
782
    public function getRelatedResourceReference(
783
        ResourceSet $sourceResourceSet,
784
        $sourceEntity,
785
        ResourceSet $targetResourceSet,
786
        ResourceProperty $targetProperty
787
    ) {
788
        return $this->getProviderWrapper()->getRelatedResourceReference(
789
            $sourceResourceSet,
790
            $sourceEntity,
791
            $targetResourceSet,
792
            $targetProperty
793
        );
794
    }
795
796
    /**
797
     * Updates a resource.
798
     *
799
     * @param ResourceSet   $sourceResourceSet    The entity set containing the source entity
800
     * @param object        $sourceEntityInstance The source entity instance
801
     * @param KeyDescriptor $keyDescriptor        The key identifying the entity to fetch
802
     * @param object        $data                 the New data for the entity instance
803
     * @param bool          $shouldUpdate         Should undefined values be updated or reset to default
804
     *
805
     * @return object|null the new resource value if it is assignable, or throw exception for null
806
     */
807
    public function updateResource(
808
        ResourceSet $sourceResourceSet,
809
        $sourceEntityInstance,
810
        KeyDescriptor $keyDescriptor,
811
        $data,
812
        $shouldUpdate = false
813
    ) {
814
        return $this->getProviderWrapper()->updateResource(
815
            $sourceResourceSet,
816
            $sourceEntityInstance,
817
            $keyDescriptor,
818
            $data,
819
            $shouldUpdate
820
        );
821
    }
822
823
    /**
824
     * Delete resource from a resource set.
825
     *
826
     * @param ResourceSet $sourceResourceSet
827
     * @param object      $sourceEntityInstance
828
     *
829
     * @return bool true if resources successfully deleted, otherwise false
830
     */
831
    public function deleteResource(
0 ignored issues
show
Coding Style introduced by
function deleteResource() does not seem to conform to the naming convention (^(?:is|has|should|may|supports)).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
832
        ResourceSet $sourceResourceSet,
833
        $sourceEntityInstance
834
    ) {
835
        return $this->getProviderWrapper()->deleteResource(
836
            $sourceResourceSet,
837
            $sourceEntityInstance
838
        );
839
    }
840
841
    /**
842
     * @param ResourceSet $resourceSet          The entity set containing the entity to fetch
843
     * @param object      $sourceEntityInstance The source entity instance
844
     * @param object      $data                 The New data for the entity instance.
845
     *
846
     * @return object|null returns the newly created model if successful, or null if model creation failed.
847
     */
848
    public function createResourceforResourceSet(
849
        ResourceSet $resourceSet,
850
        $sourceEntityInstance,
851
        $data
852
    ) {
853
        return $this->getProviderWrapper()->createResourceforResourceSet(
854
            $resourceSet,
855
            $sourceEntityInstance,
856
            $data
857
        );
858
    }
859
860
    public function getMetadataXML()
0 ignored issues
show
Documentation introduced by
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...
861
    {
862
        return $this->metaProvider->getXML();
863
    }
864
}
865