Passed
Pull Request — master (#133)
by Alex
04:55
created

ProvidersWrapper::getMetaProvider()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 5
rs 9.4285
cc 1
eloc 3
nc 1
nop 0
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
    }
102
103
    /**
104
     * @return ProvidersQueryWrapper
105
     */
106
    public function getProviderWrapper()
107
    {
108
        assert(null != $this->providerWrapper, 'Provider wrapper must be set');
109
        return $this->providerWrapper;
110
    }
111
112
    /**
113
     * @return IMetadataProvider
114
     */
115
    public function getMetaProvider()
116
    {
117
        assert(null != $this->metaProvider, 'Metadata provider must be set');
118
        return $this->metaProvider;
119
    }
120
121
    //Wrappers for IMetadataProvider methods
122
123
    /**
124
     * To get the Container name for the data source,
125
     * Note: Wrapper for IMetadataProvider::getContainerName method
126
     * implementation.
127
     *
128
     * @throws ODataException Exception if implementation returns empty container name
129
     *
130
     * @return string that contains the name of the container
131
     */
132
    public function getContainerName()
133
    {
134
        $containerName = $this->getMetaProvider()->getContainerName();
135
        if (empty($containerName)) {
136
            throw new ODataException(
137
                Messages::providersWrapperContainerNameMustNotBeNullOrEmpty(),
138
                500
139
            );
140
        }
141
142
        return $containerName;
143
    }
144
145
    /**
146
     * To get Namespace name for the data source,
147
     * Note: Wrapper for IMetadataProvider::getContainerNamespace method implementation.
148
     *
149
     * @throws ODataException Exception if implementation returns empty container namespace
150
     *
151
     * @return string that contains the namespace name
152
     */
153
    public function getContainerNamespace()
154
    {
155
        $containerNamespace = $this->getMetaProvider()->getContainerNamespace();
156
        if (empty($containerNamespace)) {
157
            throw new ODataException(
158
                Messages::providersWrapperContainerNamespaceMustNotBeNullOrEmpty(),
159
                500
160
            );
161
        }
162
163
        return $containerNamespace;
164
    }
165
166
    /**
167
     * To get the data service configuration.
168
     *
169
     * @return IServiceConfiguration
170
     */
171
    public function getConfiguration()
172
    {
173
        return $this->config;
174
    }
175
176
    /**
177
     *  To get all entity set information,
178
     *  Note: Wrapper for IMetadataProvider::getResourceSets method implementation,
179
     *  This method returns array of ResourceSetWrapper instances but the corresponding IDSMP method
180
     *  returns array of ResourceSet instances.
181
     *
182
     *  @throws ODataException when two resource sets with the same name are encountered
183
     *
184
     *  @return ResourceSetWrapper[] The ResourceSetWrappers for the visible ResourceSets
185
     */
186
    public function getResourceSets()
187
    {
188
        $resourceSets = $this->getMetaProvider()->getResourceSets();
189
        $resourceSetWrappers = [];
190
        $resourceSetNames = [];
191
        foreach ($resourceSets as $resourceSet) {
192
            $name = $resourceSet->getName();
193
            if (in_array($name, $resourceSetNames)) {
194
                throw new ODataException(Messages::providersWrapperEntitySetNameShouldBeUnique($name), 500);
195
            }
196
197
            $resourceSetNames[] = $name;
198
            $resourceSetWrapper = $this->validateResourceSetAndGetWrapper($resourceSet);
199
            if (null !== $resourceSetWrapper) {
200
                $resourceSetWrappers[] = $resourceSetWrapper;
201
            }
202
        }
203
204
        return $resourceSetWrappers;
205
    }
206
207
    /**
208
     * This function perform the following operations
209
     *  (1) If the cache contain an entry [key, value] for the resourceset then
210
     *      return the entry-value
211
     *  (2) If the cache not contain an entry for the resourceset then validate
212
     *      the resourceset
213
     *            (a) If valid add entry as [resouceset_name, resourceSetWrapper]
214
     *            (b) if not valid add entry as [resouceset_name, null]
215
     *  Note: validating a resourceset means checking the resourceset is visible
216
     *  or not using configuration.
217
     *
218
     * @param ResourceSet $resourceSet The resourceset to validate and get the
219
     *                                 wrapper for
220
     *
221
     * @return ResourceSetWrapper|null Returns an instance if a resource set with the given name is visible
222
     */
223
    private function validateResourceSetAndWrapper(ResourceSet $resourceSet)
224
    {
225
        $cacheKey = $resourceSet->getName();
226
        if (array_key_exists($cacheKey, $this->setWrapperCache)) {
227
            return $this->setWrapperCache[$cacheKey];
228
        }
229
230
        $this->validateResourceType($resourceSet->getResourceType());
231
        $wrapper = new ResourceSetWrapper($resourceSet, $this->config);
232
        $nuVal = $wrapper->isVisible() ? $wrapper : null;
233
        $this->setWrapperCache[$cacheKey] = $nuVal;
234
235
        return $this->setWrapperCache[$cacheKey];
236
    }
237
238
    /**
239
     * Validates the given instance of ResourceType.
240
     *
241
     * @param ResourceType $resourceType The ResourceType to validate
242
     *
243
     * @throws ODataException Exception if $resourceType is invalid
244
     *
245
     * @return ResourceType
246
     */
247
    private function validateResourceType(ResourceType $resourceType)
248
    {
249
        $cacheKey = $resourceType->getName();
250
        if (array_key_exists($cacheKey, $this->typeCache)) {
251
            return $this->typeCache[$cacheKey];
252
        }
253
254
        //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...
255
        $this->typeCache[$cacheKey] = $resourceType;
256
257
        return $resourceType;
258
    }
259
260
    /**
261
     * To get all resource types in the data source,
262
     * Note: Wrapper for IMetadataProvider::getTypes method implementation.
263
     *
264
     * @throws ODataException
265
     * @return ResourceType[]
266
     */
267
    public function getTypes()
268
    {
269
        $resourceTypes = $this->getMetaProvider()->getTypes();
270
        $resourceTypeNames = [];
271
        foreach ($resourceTypes as $resourceType) {
272
            if (in_array($resourceType->getName(), $resourceTypeNames)) {
273
                throw new ODataException(
274
                    Messages::providersWrapperEntityTypeNameShouldBeUnique($resourceType->getName()),
275
                    500
276
                );
277
            }
278
279
            $resourceTypeNames[] = $resourceType->getName();
280
            $this->validateResourceType($resourceType);
281
        }
282
283
        return $resourceTypes;
284
    }
285
286
    public function getSingletons()
287
    {
288
        $singletons = $this->getMetaProvider()->getSingletons();
289
        return (null == $singletons) ? [] : $singletons;
290
    }
291
292
    /**
293
     * To get a resource set based on the specified resource set name which is
294
     * visible,
295
     * Note: Wrapper for IMetadataProvider::resolveResourceSet method
296
     * implementation.
297
     *
298
     * @param string $name Name of the resource set
299
     *
300
     * @return ResourceSetWrapper|null Returns resource set with the given name if found,
301
     *                                 NULL if resource set is set to invisible or not found
302
     */
303
    public function resolveResourceSet($name)
304
    {
305
        if (array_key_exists($name, $this->setWrapperCache)) {
306
            return $this->setWrapperCache[$name];
307
        }
308
309
        $resourceSet = $this->getMetaProvider()->resolveResourceSet($name);
310
        if (null === $resourceSet) {
311
            return null;
312
        }
313
314
        return $this->validateResourceSetAndWrapper($resourceSet);
315
    }
316
317
    /**
318
     * To get a resource type based on the resource set name,
319
     * Note: Wrapper for IMetadataProvider::resolveResourceType
320
     * method implementation.
321
     *
322
     * @param string $name Name of the resource set
323
     *
324
     * @throws ODataException If the ResourceType is invalid
325
     *
326
     * @return ResourceType|null resource type with the given resource set name if found else NULL
327
     */
328
    public function resolveResourceType($name)
329
    {
330
        $resourceType = $this->getMetaProvider()->resolveResourceType($name);
331
        if (null === $resourceType) {
332
            return null;
333
        }
334
335
        return $this->validateResourceType($resourceType);
336
    }
337
338
    /**
339
     * Try to resolve named singleton
340
     *
341
     * @param string $name
342
     * @return mixed|null
343
     */
344
    public function resolveSingleton($name)
345
    {
346
        $singletons = $this->getMetaProvider()->getSingletons();
347
        if (array_key_exists($name, $singletons)) {
348
            return $singletons[$name];
349
        }
350
        return null;
351
    }
352
353
    /**
354
     * The method must return a collection of all the types derived from
355
     * $resourceType The collection returned should NOT include the type
356
     * passed in as a parameter
357
     * Note: Wrapper for IMetadataProvider::getDerivedTypes
358
     * method implementation.
359
     *
360
     * @param ResourceEntityType $resourceType Resource to get derived resource types from
361
     *
362
     * @throws InvalidOperationException when the meat provider doesn't return an array
363
     *
364
     * @return ResourceType[]
365
     */
366
    public function getDerivedTypes(ResourceEntityType $resourceType)
367
    {
368
        $derivedTypes = $this->getMetaProvider()->getDerivedTypes($resourceType);
369
        if (!is_array($derivedTypes)) {
370
            throw new InvalidOperationException(
371
                Messages::metadataAssociationTypeSetInvalidGetDerivedTypesReturnType($resourceType->getName())
372
            );
373
        }
374
375
        foreach ($derivedTypes as $derivedType) {
376
            $this->validateResourceType($derivedType);
377
        }
378
379
        return $derivedTypes;
380
    }
381
382
    /**
383
     * Returns true if $resourceType represents an Entity Type which has derived
384
     * Entity Types, else false.
385
     * Note: Wrapper for IMetadataProvider::hasDerivedTypes method implementation.
386
     *
387
     * @param ResourceEntityType    $resourceType   Resource to check for derived resource types
388
     *
389
     * @throws ODataException If the ResourceType is invalid
390
     *
391
     * @return bool
392
     */
393
    public function hasDerivedTypes(ResourceEntityType $resourceType)
394
    {
395
        $this->validateResourceType($resourceType);
396
397
        return $this->getMetaProvider()->hasDerivedTypes($resourceType);
398
    }
399
400
    /**
401
     * Gets the visible resource properties for the given resource type from the given resource set wrapper.
402
     *
403
     * @param ResourceSetWrapper $setWrapper   Resource set wrapper in question
404
     * @param ResourceType       $resourceType Resource type in question
405
     *
406
     * @return ResourceProperty[] Collection of visible resource properties from the given resource set wrapper
407
     *                            and resource type
408
     */
409
    public function getResourceProperties(ResourceSetWrapper $setWrapper, ResourceType $resourceType)
410
    {
411
        if (!$resourceType instanceof ResourceEntityType) {
412
            //Complex resource type
413
            return $resourceType->getAllProperties();
414
        }
415
        //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...
416
        $cacheKey = $setWrapper->getName() . '_' . $resourceType->getFullName();
417
        if (!array_key_exists($cacheKey, $this->propertyCache)) {
418
            //Fill the cache
419
            $this->propertyCache[$cacheKey] = [];
420
            foreach ($resourceType->getAllProperties() as $resourceProperty) {
421
                $this->propertyCache[$cacheKey][$resourceProperty->getName()] = $resourceProperty;
422
            }
423
        }
424
425
        return $this->propertyCache[$cacheKey];
426
    }
427
428
    /**
429
     * Gets the target resource set wrapper for the given navigation property,
430
     * source resource set wrapper and the source resource type.
431
     *
432
     * @param ResourceSetWrapper $resourceSetWrapper         Source resource set
433
     * @param ResourceEntityType $resourceType               Source resource type
434
     * @param ResourceProperty   $navigationResourceProperty Navigation property
435
     *
436
     * @return ResourceSetWrapper|null Returns instance of ResourceSetWrapper
437
     *                                 (describes the entity set and associated configuration) for the
438
     *                                 given navigation property. returns NULL if resourceset for the
439
     *                                 navigation property is invisible or if metadata provider returns
440
     *                                 null resource association set
441
     */
442
    public function getResourceSetWrapperForNavigationProperty(
443
        ResourceSetWrapper $resourceSetWrapper,
444
        ResourceEntityType $resourceType,
445
        ResourceProperty $navigationResourceProperty
446
    ) {
447
        $associationSet = $this->getResourceAssociationSet(
448
            $resourceSetWrapper,
449
            $resourceType,
450
            $navigationResourceProperty
451
        );
452
453
        if (null !== $associationSet) {
454
            $relatedAssociationSetEnd = $associationSet->getRelatedResourceAssociationSetEnd(
455
                $resourceSetWrapper->getResourceSet(),
456
                $resourceType,
457
                $navigationResourceProperty
458
            );
459
460
            return $this->validateResourceSetAndWrapper(
461
                $relatedAssociationSetEnd->getResourceSet()
462
            );
463
        }
464
        return null;
465
    }
466
467
    /**
468
     * Gets the ResourceAssociationSet instance for the given source association end,
469
     * Note: Wrapper for IMetadataProvider::getResourceAssociationSet
470
     * method implementation.
471
     *
472
     * @param ResourceSet        $set      Resource set of the source association end
473
     * @param ResourceEntityType $type     Resource type of the source association end
474
     * @param ResourceProperty   $property Resource property of the source association end
475
     *
476
     * @throws ODataException
477
     * @return ResourceAssociationSet|null Returns ResourceAssociationSet for the source
478
     *                                     association end, NULL if no such
479
     *                                     association end or resource set in the
480
     *                                     other end of the association is invisible
481
     */
482
    public function getResourceAssociationSet(
483
        ResourceSet $set,
484
        ResourceEntityType $type,
485
        ResourceProperty $property
486
    ) {
487
        $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...
488
        // usage below requires $type to not be null - so kaboom as early as possible
489
        assert(null != $type, 'Resource type obtained from property must not be null.');
490
        assert($type instanceof ResourceEntityType);
491
492
        $associationSet = $this->getMetaProvider()->getResourceAssociationSet(
493
            $set,
494
            $type,
495
            $property
496
        );
497
        assert(
498
            null == $associationSet || $associationSet instanceof ResourceAssociationSet,
499
            'Retrieved resource association must be either null or an instance of ResourceAssociationSet'
500
        );
501
502
        if (null !== $associationSet) {
503
            $thisAssociationSetEnd = $associationSet->getResourceAssociationSetEnd(
504
                $set,
505
                $type,
506
                $property
507
            );
508
509
            $relatedAssociationSetEnd = $associationSet->getRelatedResourceAssociationSetEnd(
510
                $set,
511
                $type,
512
                $property
513
            );
514
515
            //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...
516
            //is null means the associationset we got from the IDSMP::getResourceAssociationSet is invalid.
517
518
            //Return null, if either AssociationSet's End1 or End2's resourceset name
519
            //doesn't match the name of resource set wrapper (param1) and resource type is not assignable
520
            //from given resource type (param2)
521
            if (null === $thisAssociationSetEnd || null === $relatedAssociationSetEnd) {
522
                throw new ODataException(
523
                    Messages::providersWrapperIDSMPGetResourceSetReturnsInvalidResourceSet(
524
                        $set->getName(),
525
                        $type->getFullName(),
526
                        $property->getName()
527
                    ),
528
                    500
529
                );
530
            }
531
532
            $relatedResourceSetWrapper = $this->validateResourceSetAndWrapper(
533
                $relatedAssociationSetEnd->getResourceSet()
534
            );
535
            if ($relatedResourceSetWrapper === null) {
536
                $associationSet = null;
537
            } else {
538
                $this->validateResourceType($thisAssociationSetEnd->getResourceType());
539
                $this->validateResourceType($relatedAssociationSetEnd->getResourceType());
540
            }
541
        }
542
        assert(
543
            null == $associationSet || $associationSet instanceof ResourceAssociationSet,
544
            'Retrieved resource assocation must be either null or an instance of ResourceAssociationSet'
545
        );
546
547
        return $associationSet;
548
    }
549
550
    /**
551
     * Gets the resource type on which the resource property is declared on,
552
     * If property is not declared in the given resource type, then this
553
     * function drill down to the inheritance hierarchy of the given resource
554
     * type to find out the base class in which the property is declared.
555
     *
556
     * @param ResourceType     $type     The resource type to start looking
557
     * @param ResourceProperty $property The resource property in question
558
     *
559
     * @return ResourceType|null Returns reference to the ResourceType on which
560
     *                           the $property is declared, NULL if
561
     *                           $property is not declared anywhere
562
     *                           in the inheritance hierarchy
563
     */
564
    private function getResourceTypeWherePropertyIsDeclared(ResourceType $type, ResourceProperty $property)
565
    {
566
        while (null !== $type) {
567
            if (null !== $type->resolvePropertyDeclaredOnThisType($property->getName())) {
568
                break;
569
            }
570
571
            $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...
572
        }
573
574
        return $type;
575
    }
576
577
    /**
578
     * Wrapper function over _validateResourceSetAndGetWrapper function.
579
     *
580
     * @param ResourceSet $resourceSet see the comments of _validateResourceSetAndGetWrapper
581
     *
582
     * @return ResourceSetWrapper|null see the comments of _validateResourceSetAndGetWrapper
583
     */
584
    public function validateResourceSetAndGetWrapper(ResourceSet $resourceSet)
585
    {
586
        return $this->validateResourceSetAndWrapper($resourceSet);
587
    }
588
589
    /**
590
     * Gets the Edm Schema version compliance to the metadata.
591
     *
592
     * @return EdmSchemaVersion
593
     */
594
    public function getEdmSchemaVersion()
595
    {
596
        //The minimal schema version for custom provider is 1.1
597
        return EdmSchemaVersion::VERSION_1_DOT_1;
598
    }
599
600
    /**
601
     * Gets the underlying custom expression provider, the end developer is
602
     * responsible for implementing IExpressionProvider if he choose for.
603
     *
604
     * @return IExpressionProvider Instance of IExpressionProvider implementation
605
     */
606
    public function getExpressionProvider()
607
    {
608
        return $this->getProviderWrapper()->getExpressionProvider();
609
    }
610
611
    /**
612
     * Indicates if the QueryProvider can handle ordered paging, this means respecting order, skip, and top parameters
613
     * If the query provider can not handle ordered paging, it must return the entire result set and POData will
614
     * perform the ordering and paging.
615
     *
616
     * @return bool True if the query provider can handle ordered paging, false if POData should perform the paging
617
     */
618
    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...
619
    {
620
        return $this->getProviderWrapper()->handlesOrderedPaging();
621
    }
622
623
    /**
624
     * Gets collection of entities belongs to an entity set.
625
     *
626
     * @param QueryType                 $queryType   Indicates if this is a query for a count, entities, or entities
627
     *                                               with a count
628
     * @param ResourceSet               $resourceSet The entity set containing the entities that need to be fetched
629
     * @param FilterInfo|null           $filterInfo  Represents the $filter parameter of the OData query.
630
     *                                               NULL if no $filter specified
631
     * @param InternalOrderByInfo|null  $orderBy     The orderBy information
632
     * @param integer|null              $top         The top count
633
     * @param integer|null              $skip        The skip count
634
     * @param SkipTokenInfo|null        $skipToken   The skip token
635
     *
636
     * @return QueryResult
637
     */
638
    public function getResourceSet(
639
        QueryType $queryType,
640
        ResourceSet $resourceSet,
641
        FilterInfo $filterInfo = null,
642
        InternalOrderByInfo $orderBy = null,
643
        $top = null,
644
        $skip = null,
645
        SkipTokenInfo $skipToken = null
646
    ) {
647
        return $this->getProviderWrapper()->getResourceSet(
648
            $queryType,
649
            $resourceSet,
650
            $filterInfo,
651
            $orderBy,
652
            $top,
653
            $skip,
654
            $skipToken
655
        );
656
    }
657
658
    /**
659
     * Gets an entity instance from an entity set identified by a key.
660
     *
661
     * @param ResourceSet   $resourceSet   The entity set containing the entity to fetch
662
     * @param KeyDescriptor $keyDescriptor The key identifying the entity to fetch
663
     *
664
     * @return object|null Returns entity instance if found, else null
665
     */
666
    public function getResourceFromResourceSet(ResourceSet $resourceSet, KeyDescriptor $keyDescriptor)
667
    {
668
        return $this->getProviderWrapper()->getResourceFromResourceSet($resourceSet, $keyDescriptor);
669
    }
670
671
    /**
672
     * Puts an entity instance to entity set identified by a key.
673
     *
674
     * @param ResourceSet   $resourceSet   The entity set containing the entity to update
675
     * @param KeyDescriptor $keyDescriptor The key identifying the entity to update
676
     * @param mixed         $data
677
     *
678
     * @return bool|null Returns result of executing query
679
     */
680
    public function putResource(
681
        ResourceSet $resourceSet,
682
        KeyDescriptor $keyDescriptor,
683
        $data
684
    ) {
685
        return $this->getProviderWrapper()->putResource(
686
            $resourceSet,
687
            $keyDescriptor,
688
            $data
689
        );
690
    }
691
692
    /**
693
     * Get related resource set for a resource.
694
     *
695
     * @param QueryType          $queryType         Indicates if this is a query for a count, entities, or entities
696
     *                                              with a count
697
     * @param ResourceSet        $sourceResourceSet The entity set containing the source entity
698
     * @param object             $sourceEntity      The source entity instance
699
     * @param ResourceSet        $targetResourceSet The resource set containing the target of the navigation property
700
     * @param ResourceProperty   $targetProperty    The navigation property to retrieve
701
     * @param FilterInfo|null    $filterInfo        Represents the $filter parameter of the OData query.
702
     *                                              NULL if no $filter specified
703
     * @param mixed              $orderBy           sorted order if we want to get the data in some specific order
704
     * @param int                $top               number of records which need to be retrieved
705
     * @param int                $skip              number of records which need to be skipped
706
     * @param SkipTokenInfo|null $skipToken         value indicating what records to skip
707
     *
708
     * @throws ODataException
709
     *
710
     * @return QueryResult
711
     */
712
    public function getRelatedResourceSet(
713
        QueryType $queryType,
714
        ResourceSet $sourceResourceSet,
715
        $sourceEntity,
716
        ResourceSet $targetResourceSet,
717
        ResourceProperty $targetProperty,
718
        $filterInfo,
719
        $orderBy,
720
        $top,
721
        $skip,
722
        SkipTokenInfo $skipToken = null
723
    ) {
724
        return $this->getProviderWrapper()->getRelatedResourceSet(
725
            $queryType,
726
            $sourceResourceSet,
727
            $sourceEntity,
728
            $targetResourceSet,
729
            $targetProperty,
730
            $filterInfo,
0 ignored issues
show
Bug introduced by
It seems like $filterInfo defined by parameter $filterInfo on line 718 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...
731
            $orderBy,
732
            $top,
733
            $skip,
734
            $skipToken
735
        );
736
    }
737
738
    /**
739
     * Gets a related entity instance from an entity set identified by a key.
740
     *
741
     * @param ResourceSet      $sourceResourceSet The entity set related to the entity to be fetched
742
     * @param object           $sourceEntity      The related entity instance
743
     * @param ResourceSet      $targetResourceSet The entity set from which entity needs to be fetched
744
     * @param ResourceProperty $targetProperty    The metadata of the target property
745
     * @param KeyDescriptor    $keyDescriptor     The key to identify the entity to be fetched
746
     *
747
     * @return object|null Returns entity instance if found, else null
748
     */
749
    public function getResourceFromRelatedResourceSet(
750
        ResourceSet $sourceResourceSet,
751
        $sourceEntity,
752
        ResourceSet $targetResourceSet,
753
        ResourceProperty $targetProperty,
754
        KeyDescriptor $keyDescriptor
755
    ) {
756
        return $this->getProviderWrapper()->getResourceFromRelatedResourceSet(
757
            $sourceResourceSet,
758
            $sourceEntity,
759
            $targetResourceSet,
760
            $targetProperty,
761
            $keyDescriptor
762
        );
763
    }
764
765
    /**
766
     * Get related resource for a resource.
767
     *
768
     * @param ResourceSet      $sourceResourceSet The source resource set
769
     * @param object           $sourceEntity      The source resource
770
     * @param ResourceSet      $targetResourceSet The resource set of the navigation
771
     *                                            property
772
     * @param ResourceProperty $targetProperty    The navigation property to be
773
     *                                            retrieved
774
     *
775
     * @return object|null The related resource if exists, else null
776
     */
777
    public function getRelatedResourceReference(
778
        ResourceSet $sourceResourceSet,
779
        $sourceEntity,
780
        ResourceSet $targetResourceSet,
781
        ResourceProperty $targetProperty
782
    ) {
783
        return $this->getProviderWrapper()->getRelatedResourceReference(
784
            $sourceResourceSet,
785
            $sourceEntity,
786
            $targetResourceSet,
787
            $targetProperty
788
        );
789
    }
790
791
    /**
792
     * Updates a resource.
793
     *
794
     * @param ResourceSet   $sourceResourceSet    The entity set containing the source entity
795
     * @param object        $sourceEntityInstance The source entity instance
796
     * @param KeyDescriptor $keyDescriptor        The key identifying the entity to fetch
797
     * @param object        $data                 the New data for the entity instance
798
     * @param bool          $shouldUpdate         Should undefined values be updated or reset to default
799
     *
800
     * @return object|null the new resource value if it is assignable, or throw exception for null
801
     */
802
    public function updateResource(
803
        ResourceSet $sourceResourceSet,
804
        $sourceEntityInstance,
805
        KeyDescriptor $keyDescriptor,
806
        $data,
807
        $shouldUpdate = false
808
    ) {
809
        return $this->getProviderWrapper()->updateResource(
810
            $sourceResourceSet,
811
            $sourceEntityInstance,
812
            $keyDescriptor,
813
            $data,
814
            $shouldUpdate
815
        );
816
    }
817
818
    /**
819
     * Delete resource from a resource set.
820
     *
821
     * @param ResourceSet $sourceResourceSet
822
     * @param object      $sourceEntityInstance
823
     *
824
     * @return bool true if resources successfully deleted, otherwise false
825
     */
826
    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...
827
        ResourceSet $sourceResourceSet,
828
        $sourceEntityInstance
829
    ) {
830
        return $this->getProviderWrapper()->deleteResource(
831
            $sourceResourceSet,
832
            $sourceEntityInstance
833
        );
834
    }
835
836
    /**
837
     * @param ResourceSet $resourceSet          The entity set containing the entity to fetch
838
     * @param object      $sourceEntityInstance The source entity instance
839
     * @param object      $data                 The New data for the entity instance.
840
     *
841
     * @return object|null returns the newly created model if successful, or null if model creation failed.
842
     */
843
    public function createResourceforResourceSet(
844
        ResourceSet $resourceSet,
845
        $sourceEntityInstance,
846
        $data
847
    ) {
848
        return $this->getProviderWrapper()->createResourceforResourceSet(
849
            $resourceSet,
850
            $sourceEntityInstance,
851
            $data
852
        );
853
    }
854
855
    /**
856
     * @return mixed
857
     */
858
    public function getMetadataXML()
859
    {
860
        return $this->getMetaProvider()->getXML();
861
    }
862
}
863