Completed
Push — master ( 56c97f...f4aeff )
by Christopher
14s
created

UriProcessorNew::executePost()   C

Complexity

Conditions 8
Paths 8

Size

Total Lines 73
Code Lines 58

Duplication

Lines 5
Ratio 6.85 %

Importance

Changes 0
Metric Value
dl 5
loc 73
rs 6.3384
c 0
b 0
f 0
cc 8
eloc 58
nc 8
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace POData\UriProcessor;
4
5
use POData\Common\HttpStatus;
6
use POData\Common\Messages;
7
use POData\Common\ODataConstants;
8
use POData\Common\ODataException;
9
use POData\IService;
10
use POData\ObjectModel\CynicDeserialiser;
11
use POData\ObjectModel\ModelDeserialiser;
12
use POData\ObjectModel\ODataEntry;
13
use POData\ObjectModel\ODataURL;
14
use POData\OperationContext\HTTPRequestMethod;
15
use POData\Providers\Metadata\ResourcePropertyKind;
16
use POData\Providers\Metadata\ResourceSet;
17
use POData\Providers\Metadata\ResourceSetWrapper;
18
use POData\Providers\ProvidersWrapper;
19
use POData\Providers\Query\QueryResult;
20
use POData\Providers\Query\QueryType;
21
use POData\UriProcessor\Interfaces\IUriProcessor;
22
use POData\UriProcessor\QueryProcessor\QueryProcessor;
23
use POData\UriProcessor\ResourcePathProcessor\ResourcePathProcessor;
24
use POData\UriProcessor\ResourcePathProcessor\SegmentParser\KeyDescriptor;
25
use POData\UriProcessor\ResourcePathProcessor\SegmentParser\SegmentDescriptor;
26
use POData\UriProcessor\ResourcePathProcessor\SegmentParser\SegmentParser;
27
use POData\UriProcessor\ResourcePathProcessor\SegmentParser\TargetKind;
28
use POData\UriProcessor\ResourcePathProcessor\SegmentParser\TargetSource;
29
30
/**
31
 * Class UriProcessorNew.
32
 *
33
 * A type to process client's requested URI
34
 * The syntax of request URI is:
35
 *  Scheme Host Port ServiceRoot ResourcePath ? QueryOption
36
 * For more details refer:
37
 * http://www.odata.org/developers/protocols/uri-conventions#UriComponents
38
 */
39
class UriProcessorNew implements IUriProcessor
0 ignored issues
show
Coding Style introduced by
Since you have declared the constructor as private, maybe you should also declare the class as final.
Loading history...
40
{
41
    /**
42
     * Description of the OData request that a client has submitted.
43
     *
44
     * @var RequestDescription
45
     */
46
    private $request;
47
48
    /**
49
     * Holds reference to the data service instance.
50
     *
51
     * @var IService
52
     */
53
    private $service;
54
55
    /**
56
     * Holds reference to the wrapper over IDSMP and IDSQP implementation.
57
     *
58
     * @var ProvidersWrapper
59
     */
60
    private $providers;
61
62
    /**
63
     * Holds reference to request expander.
64
     *
65
     * @var RequestExpander
66
     */
67
    private $expander;
68
69
    /**
70
     * @var ModelDeserialiser
71
     */
72
    private $cereal;
73
74
    /**
75
     * @var CynicDeserialiser
76
     */
77
    private $cynicDeserialiser;
78
79
    /**
80
     * Constructs a new instance of UriProcessor.
81
     *
82
     * @param IService $service Reference to the data service instance
83
     */
84
    private function __construct(IService $service)
85
    {
86
        $this->service = $service;
87
        $this->providers = $service->getProvidersWrapper();
88
        $this->request = ResourcePathProcessor::process($service);
89
        $this->expander = new RequestExpander(
90
            $this->getRequest(),
91
            $this->getService(),
92
            $this->getProviders()
93
        );
94
        $this->getRequest()->setUriProcessor($this);
95
        $this->cereal = new ModelDeserialiser();
96
        $this->cynicDeserialiser = new CynicDeserialiser(
97
            $service->getMetadataProvider(),
98
            $service->getProvidersWrapper()
99
        );
100
    }
101
102
    /**
103
     * Process the resource path and query options of client's request uri.
104
     *
105
     * @param IService $service Reference to the data service instance
106
     *
107
     * @throws ODataException
108
     *
109
     * @return IUriProcessor
110
     */
111
    public static function process(IService $service)
112
    {
113
        $absRequestUri = $service->getHost()->getAbsoluteRequestUri();
114
        $absServiceUri = $service->getHost()->getAbsoluteServiceUri();
115
116
        if (!$absServiceUri->isBaseOf($absRequestUri)) {
117
            throw ODataException::createInternalServerError(
118
                Messages::uriProcessorRequestUriDoesNotHaveTheRightBaseUri(
119
                    $absRequestUri->getUrlAsString(),
120
                    $absServiceUri->getUrlAsString()
121
                )
122
            );
123
        }
124
125
        $processor = new self($service);
126
        //Parse the query string options of the request Uri.
127
        QueryProcessor::process($processor->request, $service);
128
        return $processor;
129
    }
130
131
    /**
132
     * Gets reference to the request submitted by client.
133
     *
134
     * @return RequestDescription
135
     */
136
    public function getRequest()
137
    {
138
        return $this->request;
139
    }
140
141
    /**
142
     * Gets reference to the request submitted by client.
143
     *
144
     * @return ProvidersWrapper
145
     */
146
    public function getProviders()
147
    {
148
        return $this->providers;
149
    }
150
151
    /**
152
     * Gets the data service instance.
153
     *
154
     * @return IService
155
     */
156
    public function getService()
157
    {
158
        return $this->service;
159
    }
160
161
    /**
162
     * Gets the request expander instance.
163
     *
164
     * @return RequestExpander
165
     */
166
    public function getExpander()
167
    {
168
        return $this->expander;
169
    }
170
171
    /**
172
     * @return ModelDeserialiser
173
     */
174
    public function getModelDeserialiser()
175
    {
176
        return $this->cereal;
177
    }
178
179
    public function getCynicDeserialiser()
180
    {
181
        return $this->cynicDeserialiser;
182
    }
183
184
    /**
185
     * Execute the client submitted request against the data source.
186
     */
187
    public function execute()
188
    {
189
        $service = $this->getService();
190
        assert($service instanceof IService, '!($service instanceof IService)');
191
        $context = $service->getOperationContext();
192
        $method = $context->incomingRequest()->getMethod();
193
194
        switch ($method) {
195
            case HTTPRequestMethod::GET():
196
                $this->executeGet();
197
                break;
198
            case HTTPRequestMethod::DELETE():
199
                $this->executeGet();
200
                $this->executeDelete();
201
                break;
202
            case HTTPRequestMethod::PUT():
203
                $this->executeGet();
204
                $this->executePut();
205
                break;
206
            case HTTPRequestMethod::POST():
207
                $this->executePost();
208
                break;
209
            default:
210
                throw ODataException::createNotImplementedError(Messages::onlyReadSupport($method));
211
        }
212
213
        // Apply $select and $expand options to result set, this function will be always applied
214
        // irrespective of return value of IDSQP2::canApplyQueryOptions which means library will
215
        // not delegate $expand/$select operation to IDSQP2 implementation
216
        $this->getExpander()->handleExpansion();
217
    }
218
219
    /**
220
     * Execute the client submitted request against the data source (GET).
221
     */
222
    protected function executeGet()
223
    {
224
        $segments = $this->getRequest()->getSegments();
225
        $root = $this->getRequest()->getRootProjectionNode();
226
        $eagerLoad = (null === $root) ? [] : $root->getEagerLoadList();
227
228
        foreach ($segments as $segment) {
229
            $requestTargetKind = $segment->getTargetKind();
230
231
            switch ($requestTargetKind) {
232
                case TargetKind::SINGLETON():
233
                    $this->executeGetSingleton($segment);
234
                    break;
235
                case TargetKind::RESOURCE():
236
                    $this->executeGetResource($segment, $eagerLoad);
237
                    break;
238
                case TargetKind::MEDIA_RESOURCE():
239
                    $this->checkResourceExistsByIdentifier($segment);
240
                    $segment->setResult($segment->getPrevious()->getResult());
241
                    // a media resource means we're done - bail out of segment processing
242
                    break 2;
243
                case TargetKind::LINK():
244
                    $this->executeGetLink($segment);
245
                    break;
246
                case TargetKind::PRIMITIVE_VALUE():
247
                    $previous = $segment->getPrevious();
248
                    if (null !== $previous && TargetKind::RESOURCE() == $previous->getTargetKind()) {
249
                        $result = $previous->getResult();
250
                        if ($result instanceof QueryResult) {
251
                            $raw = null !== $result->count ? $result->count : count($result->results);
252
                            $segment->setResult($raw);
253
                        }
254
                    }
255
                    break;
256
                case TargetKind::PRIMITIVE():
257
                case TargetKind::COMPLEX_OBJECT():
258
                case TargetKind::BAG():
259
                    break;
260
                default:
261
                    assert(false, 'Not implemented yet');
262
            }
263
264
            if (null === $segment->getNext()
265
                || ODataConstants::URI_COUNT_SEGMENT == $segment->getNext()->getIdentifier()
266
            ) {
267
                $this->applyQueryOptions($segment);
268
            }
269
        }
270
    }
271
272
    /**
273
     * Execute the client submitted request against the data source (DELETE).
274
     */
275
    protected function executeDelete()
276
    {
277
        $segment = $this->getFinalEffectiveSegment();
278
        $requestMethod = $this->getService()->getOperationContext()->incomingRequest()->getMethod();
279
        $resourceSet = $segment->getTargetResourceSetWrapper();
280
        $keyDescriptor = $segment->getKeyDescriptor();
281
282
        $this->checkUriValidForSuppliedVerb($resourceSet, $keyDescriptor, $requestMethod);
283
        assert($resourceSet instanceof ResourceSet);
284
        $this->getProviders()->deleteResource($resourceSet, $segment->getResult());
285
        $this->getService()->getHost()->setResponseStatusCode(HttpStatus::CODE_NOCONTENT);
286
    }
287
288
    /**
289
     * Execute the client submitted request against the data source (PUT).
290
     */
291
    protected function executePut()
292
    {
293
        $segment = $this->getFinalEffectiveSegment();
294
        $requestMethod = $this->getService()->getOperationContext()->incomingRequest()->getMethod();
295
        $resourceSet = null !== $segment ? $segment->getTargetResourceSetWrapper() : null;
296
        $keyDescriptor = null !== $segment ? $segment->getKeyDescriptor() : null;
297
298
        $this->checkUriValidForSuppliedVerb($resourceSet, $keyDescriptor, $requestMethod);
299
        assert($resourceSet instanceof ResourceSet);
300
        assert($keyDescriptor instanceof KeyDescriptor);
301
302
        $payload = $this->getRequest()->getData();
303
        assert($payload instanceof ODataEntry, get_class($payload));
304
        assert(!empty($payload->id), 'Payload ID must not be empty for PUT request');
305
        $data = $this->getModelDeserialiser()->bulkDeserialise($resourceSet->getResourceType(), $payload);
306
307
        if (empty($data)) {
308
            throw ODataException::createBadRequestError(Messages::noDataForThisVerb($requestMethod));
309
        }
310
311
        $queryResult = $this->getCynicDeserialiser()->processPayload($payload);
312
        $segment->setResult($queryResult);
313
    }
314
315
    /**
316
     * Execute the client submitted request against the data source (POST).
317
     */
318
    protected function executePost()
319
    {
320
        $segments = $this->getRequest()->getSegments();
321
        $requestMethod = $this->getService()->getOperationContext()->incomingRequest()->getMethod();
322
323
        foreach ($segments as $segment) {
324
            $requestTargetKind = $segment->getTargetKind();
325
            if ($requestTargetKind == TargetKind::RESOURCE()) {
326
                $resourceSet = $segment->getTargetResourceSetWrapper();
327 View Code Duplication
                if (!$resourceSet) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
328
                    $url = $this->getService()->getHost()->getAbsoluteRequestUri()->getUrlAsString();
329
                    $msg = Messages::badRequestInvalidUriForThisVerb($url, $requestMethod);
330
                    throw ODataException::createBadRequestError($msg);
331
                }
332
333
                $payload = $this->getRequest()->getData();
334
                if ($payload instanceof ODataURL) {
335
                    $this->executeGet();
336
                    $masterModel = $this->getRequest()->getSegments()[0]->getResult();
337
                    $masterResourceSet = $this->getRequest()->getSegments()[0]->getTargetResourceSetWrapper();
338
                    $masterNavProperty = $this->getRequest()->getLastSegment()->getIdentifier();
339
                    $slaveModelUri = new \POData\Common\Url($payload->url);
340
                    $host = $this->service->getHost();
341
                    $absoluteServiceUri = $host->getAbsoluteServiceUri();
342
                    $requestUriSegments = array_slice(
343
                        $slaveModelUri->getSegments(),
344
                        $absoluteServiceUri->getSegmentCount()
345
                    );
346
                    $newSegments = SegmentParser::parseRequestUriSegments(
347
                        $requestUriSegments,
348
                        $this->service->getProvidersWrapper(),
349
                        true
350
                    );
351
                    $this->executeGetResource($newSegments[0]);
352
                    $slaveModel = $newSegments[0]->getResult();
353
                    $slaveResourceSet = $newSegments[0]->getTargetResourceSetWrapper();
354
                    $linkAdded = $this->getProviders()
355
                        ->hookSingleModel(
356
                            $masterResourceSet,
357
                            $masterModel,
358
                            $slaveResourceSet,
359
                            $slaveModel,
360
                            $masterNavProperty
361
                        );
362
                    if ($linkAdded) {
363
                        $this->getService()->getHost()->setResponseStatusCode(HttpStatus::CODE_NOCONTENT);
364
                    } else {
365
                        throw ODataException::createInternalServerError('AdapterIndicatedLinkNotAttached');
366
                    }
367
                    foreach ($segments as $segment) {
368
                        $segment->setResult(null);
369
                    }
370
                    return;
371
                }
372
                assert($payload instanceof ODataEntry, get_class($payload));
373
                assert(empty($payload->id), 'Payload ID must be empty for POST request');
374
                $data = $this->getModelDeserialiser()->bulkDeserialise($resourceSet->getResourceType(), $payload);
375
376
                if (empty($data)) {
377
                    throw ODataException::createBadRequestError(Messages::noDataForThisVerb($requestMethod));
378
                }
379
                $this->getService()->getHost()->setResponseStatusCode(HttpStatus::CODE_CREATED);
380
                $queryResult = $this->getCynicDeserialiser()->processPayload($payload);
381
                $keyID = $payload->id;
382
                assert($keyID instanceof KeyDescriptor, get_class($keyID));
383
                $locationUrl = $keyID->generateRelativeUri($resourceSet->getResourceSet());
384
                $absoluteServiceUri = $this->getService()->getHost()->getAbsoluteServiceUri()->getUrlAsString();
385
                $location = rtrim($absoluteServiceUri, '/') . '/' . $locationUrl;
386
                $this->getService()->getHost()->setResponseLocation($location);
387
                $segment->setResult($queryResult);
388
            }
389
        }
390
    }
391
392
    /**
393
     * @return null|SegmentDescriptor
394
     */
395
    protected function getFinalEffectiveSegment()
396
    {
397
        $segment = $this->getRequest()->getLastSegment();
398
        // if last segment is $count, back up one
399
        if (null !== $segment && ODataConstants::URI_COUNT_SEGMENT == $segment->getIdentifier()) {
400
            $segment = $segment->getPrevious();
401
            return $segment;
402
        }
403
        return $segment;
404
    }
405
406
    /**
407
     * @param $resourceSet
408
     * @param $keyDescriptor
409
     * @param $requestMethod
410
     * @throws ODataException
411
     */
412
    protected function checkUriValidForSuppliedVerb($resourceSet, $keyDescriptor, $requestMethod)
413
    {
414 View Code Duplication
        if (!$resourceSet || !$keyDescriptor) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
415
            $url = $this->getService()->getHost()->getAbsoluteRequestUri()->getUrlAsString();
416
            throw ODataException::createBadRequestError(
417
                Messages::badRequestInvalidUriForThisVerb($url, $requestMethod)
418
            );
419
        }
420
    }
421
422
    /**
423
     * @param $segment
424
     */
425
    private function executeGetSingleton($segment)
426
    {
427
        $segmentId = $segment->getIdentifier();
428
        $singleton = $this->getService()->getProvidersWrapper()->resolveSingleton($segmentId);
429
        $segment->setResult($singleton->get());
430
    }
431
432
    /**
433
     * @param $segment
434
     */
435
    private function executeGetResource($segment, array $eagerList = [])
436
    {
437
        foreach ($eagerList as $eager) {
438
            assert(is_string($eager) && 0 < strlen($eager), 'Eager-load list elements must be non-empty strings');
439
        }
440
        $isRelated = $segment->getTargetSource() != TargetSource::ENTITY_SET;
441
        if (!$isRelated) {
442
            $queryResult = $this->executeGetResourceDirect($segment, $eagerList);
443
        } else {
444
            $queryResult = $this->executeGetResourceRelated($segment);
445
        }
446
        $segment->setResult($queryResult);
447
    }
448
449
    /**
450
     * @param $segment
451
     */
452
    private function executeGetLink($segment)
453
    {
454
        $previous = $segment->getPrevious();
455
        assert(isset($previous));
456
        $segment->setResult($previous->getResult());
457
    }
458
459
    /**
460
     * @param $segment
461
     * @return null|object|QueryResult
462
     */
463
    private function executeGetResourceDirect($segment, array $eagerList)
464
    {
465
        if ($segment->isSingleResult()) {
466
            $queryResult = $this->getProviders()->getResourceFromResourceSet(
467
                $segment->getTargetResourceSetWrapper(),
468
                $segment->getKeyDescriptor(),
469
                $eagerList
470
            );
471
        } else {
472
            $skip = $this->getRequest()->getSkipCount();
473
            $skip = (null === $skip) ? 0 : $skip;
474
            $skipToken = $this->getRequest()->getInternalSkipTokenInfo();
475
            $skipToken = (null != $skipToken) ? $skipToken->getSkipTokenInfo() : null;
476
            $queryResult = $this->getProviders()->getResourceSet(
477
                $this->getRequest()->queryType,
478
                $segment->getTargetResourceSetWrapper(),
479
                $this->getRequest()->getFilterInfo(),
480
                $this->getRequest()->getInternalOrderByInfo(),
481
                $this->getRequest()->getTopCount(),
482
                $skip,
483
                $skipToken,
484
                $eagerList
485
            );
486
        }
487
        return $queryResult;
488
    }
489
490
    /**
491
     * @param $segment
492
     * @return null|object|QueryResult
493
     */
494
    private function executeGetResourceRelated($segment)
495
    {
496
        $projectedProperty = $segment->getProjectedProperty();
497
        $projectedPropertyKind = null !== $projectedProperty ? $projectedProperty->getKind() : 0;
498
        $queryResult = null;
499
        switch ($projectedPropertyKind) {
500
            case ResourcePropertyKind::RESOURCE_REFERENCE:
501
                $queryResult = $this->getProviders()->getRelatedResourceReference(
502
                    $segment->getPrevious()->getTargetResourceSetWrapper(),
503
                    $segment->getPrevious()->getResult(),
504
                    $segment->getTargetResourceSetWrapper(),
505
                    $projectedProperty
506
                );
507
                break;
508
            case ResourcePropertyKind::RESOURCESET_REFERENCE:
509
                if ($segment->isSingleResult()) {
510
                    $queryResult = $this->getProviders()->getResourceFromRelatedResourceSet(
511
                        $segment->getPrevious()->getTargetResourceSetWrapper(),
512
                        $segment->getPrevious()->getResult(),
513
                        $segment->getTargetResourceSetWrapper(),
514
                        $projectedProperty,
515
                        $segment->getKeyDescriptor()
516
                    );
517
                } else {
518
                    $skipToken = $this->getRequest()->getInternalSkipTokenInfo();
519
                    $skipToken = (null !== $skipToken) ? $skipToken->getSkipTokenInfo() : null;
520
                    $queryResult = $this->getProviders()->getRelatedResourceSet(
521
                        $this->getRequest()->queryType,
522
                        $segment->getPrevious()->getTargetResourceSetWrapper(),
523
                        $segment->getPrevious()->getResult(),
524
                        $segment->getTargetResourceSetWrapper(),
525
                        $projectedProperty,
526
                        $this->getRequest()->getFilterInfo(),
527
                        null, // $orderby
528
                        null, // $top
529
                        null, // $skip
530
                        $skipToken
531
                    );
532
                }
533
                break;
534
            default:
535
                $this->checkResourceExistsByIdentifier($segment);
536
                assert(false, 'Invalid property kind type for resource retrieval');
537
        }
538
        return $queryResult;
539
    }
540
541
    /**
542
     * @param $segment
543
     * @throws ODataException
544
     */
545
    private function checkResourceExistsByIdentifier($segment)
546
    {
547
        if (null === $segment->getPrevious()->getResult()) {
548
            throw ODataException::createResourceNotFoundError(
549
                $segment->getPrevious()->getIdentifier()
550
            );
551
        }
552
    }
553
554
    /**
555
     * Applies the query options to the resource(s) retrieved from the data source.
556
     *
557
     * @param SegmentDescriptor $segment The descriptor which holds resource(s) on which query options to be applied
558
     */
559
    private function applyQueryOptions(SegmentDescriptor $segment)
560
    {
561
        $result = $segment->getResult();
562
        if (!$result instanceof QueryResult) {
563
            //If the segment isn't a query result, then there's no paging or counting to be done
564
            return;
565
        }
566
        // Note $inlinecount=allpages means include the total count regardless of paging..so we set the counts first
567
        // regardless if POData does the paging or not.
568 View Code Duplication
        if ($this->getRequest()->queryType == QueryType::ENTITIES_WITH_COUNT()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
569
            if ($this->getProviders()->handlesOrderedPaging()) {
570
                $this->getRequest()->setCountValue($result->count);
571
            } else {
572
                $this->getRequest()->setCountValue(count($result->results));
573
            }
574
        }
575
        //Have POData perform paging if necessary
576
        if (!$this->getProviders()->handlesOrderedPaging() && !empty($result->results)) {
577
            $result->results = $this->performPaging($result->results);
578
        }
579
        //a bit surprising, but $skip and $top affects $count so update it here, not above
580
        //IE  data.svc/Collection/$count?$top=10 returns 10 even if Collection has 11+ entries
581 View Code Duplication
        if ($this->getRequest()->queryType == QueryType::COUNT()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
582
            if ($this->getProviders()->handlesOrderedPaging()) {
583
                $this->getRequest()->setCountValue($result->count);
584
            } else {
585
                $this->getRequest()->setCountValue(count($result->results));
586
            }
587
        }
588
        $segment->setResult($result);
589
    }
590
591
    /**
592
     * If the provider does not perform the paging (ordering, top, skip) then this method does it.
593
     *
594
     * @param array $result
595
     *
596
     * @return array
597
     */
598
    private function performPaging(array $result)
599
    {
600
        //Apply (implicit and explicit) $orderby option
601
        $internalOrderByInfo = $this->getRequest()->getInternalOrderByInfo();
602
        if (null !== $internalOrderByInfo) {
603
            $orderByFunction = $internalOrderByInfo->getSorterFunction();
604
            usort($result, $orderByFunction);
605
        }
606
        //Apply $skiptoken option
607
        $internalSkipTokenInfo = $this->getRequest()->getInternalSkipTokenInfo();
608
        if (null !== $internalSkipTokenInfo) {
609
            $matchingIndex = $internalSkipTokenInfo->getIndexOfFirstEntryInTheNextPage($result);
610
            $result = array_slice($result, $matchingIndex);
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $result. This often makes code more readable.
Loading history...
611
        }
612
        //Apply $top and $skip option
613
        if (!empty($result)) {
614
            $top = $this->getRequest()->getTopCount();
615
            $skip = $this->getRequest()->getSkipCount();
616
            if (null === $skip) {
617
                $skip = 0;
618
            }
619
            $result = array_slice($result, $skip, $top);
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $result. This often makes code more readable.
Loading history...
620
        }
621
        return $result;
622
    }
623
}
624