Test Setup Failed
Pull Request — master (#62)
by Alex
03:03
created

IronicSerialiser::getCurrentResourceSetWrapper()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 7
rs 9.4285
cc 2
eloc 4
nc 2
nop 0
1
<?php
2
3
namespace AlgoWeb\PODataLaravel\Serialisers;
4
5
use POData\Common\Messages;
6
use POData\Common\ODataConstants;
7
use POData\Common\ODataException;
8
use POData\IService;
9
use POData\ObjectModel\IObjectSerialiser;
10
use POData\ObjectModel\ODataEntry;
11
use POData\ObjectModel\ODataFeed;
12
use POData\ObjectModel\ODataLink;
13
use POData\ObjectModel\ODataMediaLink;
14
use POData\ObjectModel\ODataNavigationPropertyInfo;
15
use POData\ObjectModel\ODataPropertyContent;
16
use POData\ObjectModel\ODataURL;
17
use POData\ObjectModel\ODataURLCollection;
18
use POData\Providers\Metadata\ResourceEntityType;
19
use POData\Providers\Metadata\ResourceProperty;
20
use POData\Providers\Metadata\ResourcePropertyKind;
21
use POData\Providers\Metadata\ResourceSet;
22
use POData\Providers\Metadata\ResourceSetWrapper;
23
use POData\Providers\Metadata\ResourceType;
24
use POData\Providers\Metadata\Type\IType;
25
use POData\Providers\Query\QueryType;
26
use POData\UriProcessor\QueryProcessor\ExpandProjectionParser\ExpandedProjectionNode;
27
use POData\UriProcessor\QueryProcessor\ExpandProjectionParser\ProjectionNode;
28
use POData\UriProcessor\RequestDescription;
29
use POData\UriProcessor\SegmentStack;
30
31
class IronicSerialiser implements IObjectSerialiser
32
{
33
    /**
34
     * The service implementation.
35
     *
36
     * @var IService
37
     */
38
    protected $service;
39
40
    /**
41
     * Request description instance describes OData request the
42
     * the client has submitted and result of the request.
43
     *
44
     * @var RequestDescription
45
     */
46
    protected $request;
47
48
    /**
49
     * Collection of complex type instances used for cycle detection.
50
     *
51
     * @var array
52
     */
53
    protected $complexTypeInstanceCollection;
54
55
    /**
56
     * Absolute service Uri.
57
     *
58
     * @var string
59
     */
60
    protected $absoluteServiceUri;
61
62
    /**
63
     * Absolute service Uri with slash.
64
     *
65
     * @var string
66
     */
67
    protected $absoluteServiceUriWithSlash;
68
69
    /**
70
     * Holds reference to segment stack being processed.
71
     *
72
     * @var SegmentStack
73
     */
74
    protected $stack;
75
76
    /**
77
     * Lightweight stack tracking for recursive descent fill
78
     */
79
    private $lightStack = [];
80
81
    /**
82
     * @param IService           $service Reference to the data service instance
83
     * @param RequestDescription $request Type instance describing the client submitted request
84
     */
85
    public function __construct(IService $service, RequestDescription $request = null)
86
    {
87
        $this->service = $service;
88
        $this->request = $request;
89
        $this->absoluteServiceUri = $service->getHost()->getAbsoluteServiceUri()->getUrlAsString();
90
        $this->absoluteServiceUriWithSlash = rtrim($this->absoluteServiceUri, '/') . '/';
91
        $this->stack = new SegmentStack($request);
92
        $this->complexTypeInstanceCollection = [];
93
    }
94
95
    /**
96
     * Write a top level entry resource.
97
     *
98
     * @param mixed $entryObject Reference to the entry object to be written
99
     *
100
     * @return ODataEntry
101
     */
102
    public function writeTopLevelElement($entryObject)
103
    {
104
        if (!isset($entryObject)) {
105
            array_pop($this->lightStack);
106
            return null;
107
        }
108
109 View Code Duplication
        if (0 == count($this->lightStack)) {
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...
110
            $typeName = $this->getRequest()->getTargetResourceType()->getName();
111
            array_push($this->lightStack, [$typeName, $typeName]);
112
        }
113
114
        $stackCount = count($this->lightStack);
115
        $topOfStack = $this->lightStack[$stackCount-1];
116
        $resourceType = $this->getService()->getProvidersWrapper()->resolveResourceType($topOfStack[0]);
117
        $rawProp = $resourceType->getAllProperties();
118
        $relProp = [];
119
        foreach ($rawProp as $prop) {
120
            if ($prop->getResourceType() instanceof ResourceEntityType) {
121
                $relProp[] = $prop;
122
            }
123
        }
124
125
        $resourceSet = $resourceType->getCustomState();
126
        assert($resourceSet instanceof ResourceSet);
127
        $title = $resourceType->getName();
128
        $type = $resourceType->getFullName();
129
130
        $relativeUri = $this->getEntryInstanceKey(
131
            $entryObject,
132
            $resourceType,
133
            $resourceSet->getName()
134
        );
135
        $absoluteUri = rtrim($this->absoluteServiceUri, '/') . '/' . $relativeUri;
136
137
        list($mediaLink, $mediaLinks) = $this->writeMediaData($entryObject, $type, $relativeUri, $resourceType);
138
139
        $propertyContent = new ODataPropertyContent();
140
141
        $links = [];
142
        foreach ($relProp as $prop) {
143
            $nuLink = new ODataLink();
144
            $propKind = $prop->getKind();
145
146
            assert(
147
                ResourcePropertyKind::RESOURCESET_REFERENCE == $propKind
148
                || ResourcePropertyKind::RESOURCE_REFERENCE == $propKind,
149
                '$propKind != ResourcePropertyKind::RESOURCESET_REFERENCE &&'
150
                .' $propKind != ResourcePropertyKind::RESOURCE_REFERENCE'
151
            );
152
            $propTail = ResourcePropertyKind::RESOURCE_REFERENCE == $propKind ? 'entry' : 'feed';
153
            $propType = 'application/atom+xml;type='.$propTail;
154
            $propName = $prop->getName();
155
            $nuLink->title = $propName;
156
            $nuLink->name = ODataConstants::ODATA_RELATED_NAMESPACE . $propName;
157
            $nuLink->url = $relativeUri . '/' . $propName;
158
            $nuLink->type = $propType;
159
160
            $navProp = new ODataNavigationPropertyInfo($prop, $this->shouldExpandSegment($propName));
161
            if ($navProp->expanded) {
162
                $nextName = $prop->getResourceType()->getName();
163
                $nuLink->isExpanded = true;
164
                $isCollection = ResourcePropertyKind::RESOURCESET_REFERENCE == $propKind;
165
                $nuLink->isCollection = $isCollection;
166
                $value = $entryObject->$propName;
167
                array_push($this->lightStack, [$nextName, $propName]);
168
                if (!$isCollection) {
169
                    $expandedResult = $this->writeTopLevelElement($value);
170
                } else {
171
                    $expandedResult = $this->writeTopLevelElements($value);
172
                }
173
                $nuLink->expandedResult = $expandedResult;
174
                if (!isset($nuLink->expandedResult)) {
175
                    $nuLink->isCollection = null;
176
                    $nuLink->isExpanded = null;
177
                } else {
178
                    if (isset($nuLink->expandedResult->selfLink)) {
179
                        $nuLink->expandedResult->selfLink->title = $propName;
180
                        $nuLink->expandedResult->selfLink->url = $nuLink->url;
181
                        $nuLink->expandedResult->title = $propName;
182
                        $nuLink->expandedResult->id = rtrim($this->absoluteServiceUri, '/') . '/' . $nuLink->url;
183
                    }
184
                }
185
            }
186
187
            $links[] = $nuLink;
188
        }
189
190
        $odata = new ODataEntry();
191
        $odata->resourceSetName = $resourceSet->getName();
192
        $odata->id = $absoluteUri;
193
        $odata->title = $title;
194
        $odata->type = $type;
195
        $odata->propertyContent = $propertyContent;
196
        $odata->isMediaLinkEntry = $resourceType->isMediaLinkEntry();
197
        $odata->editLink = $relativeUri;
198
        $odata->mediaLink = $mediaLink;
199
        $odata->mediaLinks = $mediaLinks;
200
        $odata->links = $links;
201
202
        $newCount = count($this->lightStack);
203
        assert($newCount == $stackCount, "Should have $stackCount elements in stack, have $newCount elements");
204
        array_pop($this->lightStack);
205
        return $odata;
206
    }
207
208
    /**
209
     * Write top level feed element.
210
     *
211
     * @param array &$entryObjects Array of entry resources to be written
212
     *
213
     * @return ODataFeed
214
     */
215
    public function writeTopLevelElements(&$entryObjects)
216
    {
217
        assert(is_array($entryObjects), '!is_array($entryObjects)');
218
219 View Code Duplication
        if (0 == count($this->lightStack)) {
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...
220
            $typeName = $this->getRequest()->getTargetResourceType()->getName();
221
            array_push($this->lightStack, [$typeName, $typeName]);
222
        }
223
        $setName = $this->getRequest()->getTargetResourceSetWrapper()->getName();
224
225
226
        $title = $this->getRequest()->getContainerName();
227
        $relativeUri = $this->getRequest()->getIdentifier();
228
        $absoluteUri = $this->getRequest()->getRequestUrl()->getUrlAsString();
229
230
        $selfLink = new ODataLink();
231
        $selfLink->name = 'self';
232
        $selfLink->title = $relativeUri;
233
        $selfLink->url = $relativeUri;
234
235
        $odata = new ODataFeed();
236
        $odata->title = $title;
237
        $odata->id = $absoluteUri;
238
        $odata->selfLink = $selfLink;
239
240
        if ($this->getRequest()->queryType == QueryType::ENTITIES_WITH_COUNT()) {
241
            $odata->rowCount = $this->getRequest()->getCountValue();
242
        }
243
        foreach ($entryObjects as $entry) {
244
            $odata->entries[] = $this->writeTopLevelElement($entry);
245
        }
246
247
248
        if ($this->needNextPageLink(count($entryObjects))) {
249
            $stackSegment = $setName;
250
            $lastObject = end($entryObjects);
251
            $segment = $this->getNextLinkUri($lastObject, $absoluteUri);
252
            $nextLink = new ODataLink();
253
            $nextLink->name = ODataConstants::ATOM_LINK_NEXT_ATTRIBUTE_STRING;
254
            $nextLink->url = rtrim($this->absoluteServiceUri, '/') . '/' . $stackSegment . $segment;
255
            $odata->nextPageLink = $nextLink;
256
        }
257
258
        return $odata;
259
    }
260
261
    /**
262
     * Write top level url element.
263
     *
264
     * @param mixed $entryObject The entry resource whose url to be written
265
     *
266
     * @return ODataURL
267
     */
268
    public function writeUrlElement($entryObject)
269
    {
270
        $url = new ODataURL();
271
        if (!is_null($entryObject)) {
272
            $currentResourceType = $this->getCurrentResourceSetWrapper()->getResourceType();
273
            $relativeUri = $this->getEntryInstanceKey(
274
                $entryObject,
275
                $currentResourceType,
276
                $this->getCurrentResourceSetWrapper()->getName()
277
            );
278
279
            $url->url = rtrim($this->absoluteServiceUri, '/') . '/' . $relativeUri;
280
        }
281
282
        return $url;
283
    }
284
285
    /**
286
     * Write top level url collection.
287
     *
288
     * @param array $entryObjects Array of entry resources
289
     *                            whose url to be written
290
     *
291
     * @return ODataURLCollection
292
     */
293
    public function writeUrlElements($entryObjects)
294
    {
295
        $urls = new ODataURLCollection();
296
        if (!empty($entryObjects)) {
297
            $i = 0;
298
            foreach ($entryObjects as $entryObject) {
299
                $urls->urls[$i] = $this->writeUrlElement($entryObject);
300
                ++$i;
301
            }
302
303
            if ($i > 0 && $this->needNextPageLink(count($entryObjects))) {
304
                $stackSegment = $this->getRequest()->getTargetResourceSetWrapper()->getName();
305
                $lastObject = end($entryObjects);
306
                $segment = $this->getNextLinkUri($lastObject, $this->getRequest()->getRequestUrl()->getUrlAsString());
307
                $nextLink = new ODataLink();
308
                $nextLink->name = ODataConstants::ATOM_LINK_NEXT_ATTRIBUTE_STRING;
309
                $nextLink->url = rtrim($this->absoluteServiceUri, '/') . '/' . $stackSegment . $segment;
310
                $urls->nextPageLink = $nextLink;
311
            }
312
        }
313
314
        if ($this->getRequest()->queryType == QueryType::ENTITIES_WITH_COUNT()) {
315
            $urls->count = $this->getRequest()->getCountValue();
316
        }
317
318
        return $urls;
319
    }
320
321
    /**
322
     * Write top level complex resource.
323
     *
324
     * @param mixed &$complexValue The complex object to be
325
     *                                    written
326
     * @param string $propertyName The name of the
327
     *                                    complex property
328
     * @param ResourceType &$resourceType Describes the type of
329
     *                                    complex object
330
     *
331
     * @return ODataPropertyContent
332
     * @codeCoverageIgnore
333
     */
334
    public function writeTopLevelComplexObject(&$complexValue, $propertyName, ResourceType &$resourceType)
335
    {
336
        // TODO: Figure out if we need to bother implementing this
337
    }
338
339
    /**
340
     * Write top level bag resource.
341
     *
342
     * @param mixed &$BagValue The bag object to be
343
     *                                    written
344
     * @param string $propertyName The name of the
345
     *                                    bag property
346
     * @param ResourceType &$resourceType Describes the type of
347
     *                                    bag object
348
     * @codeCoverageIgnore
349
     * @return ODataPropertyContent
350
     */
351
    public function writeTopLevelBagObject(&$BagValue, $propertyName, ResourceType &$resourceType)
352
    {
353
        // TODO: Figure out if we need to bother implementing this
354
    }
355
356
    /**
357
     * Write top level primitive value.
358
     *
359
     * @param mixed &$primitiveValue The primitve value to be
360
     *                                            written
361
     * @param ResourceProperty &$resourceProperty Resource property
362
     *                                            describing the
363
     *                                            primitive property
364
     *                                            to be written
365
     * @codeCoverageIgnore
366
     * @return ODataPropertyContent
367
     */
368
    public function writeTopLevelPrimitive(&$primitiveValue, ResourceProperty &$resourceProperty = null)
369
    {
370
        // TODO: Figure out if we need to bother implementing this
371
    }
372
373
    /**
374
     * Gets reference to the request submitted by client.
375
     *
376
     * @return RequestDescription
377
     */
378
    public function getRequest()
379
    {
380
        assert(null != $this->request, 'Request not yet set');
381
382
        return $this->request;
383
    }
384
385
    /**
386
     * Sets reference to the request submitted by client.
387
     *
388
     * @param RequestDescription $request
389
     */
390
    public function setRequest(RequestDescription $request)
391
    {
392
        $this->request = $request;
393
        $this->stack->setRequest($request);
394
    }
395
396
    /**
397
     * Gets the data service instance.
398
     *
399
     * @return IService
400
     */
401
    public function getService()
402
    {
403
        return $this->service;
404
    }
405
406
    /**
407
     * Gets the segment stack instance.
408
     *
409
     * @return SegmentStack
410
     */
411
    public function getStack()
412
    {
413
        return $this->stack;
414
    }
415
416
    protected function getEntryInstanceKey($entityInstance, ResourceType $resourceType, $containerName)
417
    {
418
        $typeName = $resourceType->getName();
419
        $keyProperties = $resourceType->getKeyProperties();
420
        assert(count($keyProperties) != 0, 'count($keyProperties) == 0');
421
        $keyString = $containerName . '(';
422
        $comma = null;
423
        foreach ($keyProperties as $keyName => $resourceProperty) {
424
            $keyType = $resourceProperty->getInstanceType();
425
            assert($keyType instanceof IType, '$keyType not instanceof IType');
426
            $keyName = $resourceProperty->getName();
427
            $keyValue = $entityInstance->$keyName;
428
            if (!isset($keyValue)) {
429
                throw ODataException::createInternalServerError(
430
                    Messages::badQueryNullKeysAreNotSupported($typeName, $keyName)
431
                );
432
            }
433
434
            $keyValue = $keyType->convertToOData($keyValue);
435
            $keyString .= $comma . $keyName . '=' . $keyValue;
436
            $comma = ',';
437
        }
438
439
        $keyString .= ')';
440
441
        return $keyString;
442
    }
443
444
    /**
445
     * @param $entryObject
446
     * @param $type
447
     * @param $relativeUri
448
     * @param $resourceType
449
     * @return array
450
     */
451
    protected function writeMediaData($entryObject, $type, $relativeUri, ResourceType $resourceType)
452
    {
453
        $context = $this->getService()->getOperationContext();
454
        $streamProviderWrapper = $this->getService()->getStreamProviderWrapper();
455
        assert(null != $streamProviderWrapper, "Retrieved stream provider must not be null");
456
457
        $mediaLink = null;
458
        if ($resourceType->isMediaLinkEntry()) {
459
            $eTag = $streamProviderWrapper->getStreamETag2($entryObject, null, $context);
0 ignored issues
show
Bug introduced by
The method getStreamETag2() does not exist on POData\Providers\Stream\StreamProviderWrapper. Did you maybe mean getStreamETag()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
460
            $mediaLink = new ODataMediaLink($type, '/$value', $relativeUri . '/$value', '*/*', $eTag);
461
        }
462
        $mediaLinks = [];
463
        if ($resourceType->hasNamedStream()) {
464
            $namedStreams = $resourceType->getAllNamedStreams();
465
            foreach ($namedStreams as $streamTitle => $resourceStreamInfo) {
466
                $readUri = $streamProviderWrapper->getReadStreamUri2(
0 ignored issues
show
Bug introduced by
The method getReadStreamUri2() does not exist on POData\Providers\Stream\StreamProviderWrapper. Did you maybe mean getReadStream()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
467
                    $entryObject,
468
                    $resourceStreamInfo,
469
                    $context,
470
                    $relativeUri
471
                );
472
                $mediaContentType = $streamProviderWrapper->getStreamContentType2(
0 ignored issues
show
Bug introduced by
The method getStreamContentType2() does not exist on POData\Providers\Stream\StreamProviderWrapper. Did you maybe mean getStreamContentType()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
473
                    $entryObject,
474
                    $resourceStreamInfo,
475
                    $context
476
                );
477
                $eTag = $streamProviderWrapper->getStreamETag2(
0 ignored issues
show
Bug introduced by
The method getStreamETag2() does not exist on POData\Providers\Stream\StreamProviderWrapper. Did you maybe mean getStreamETag()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
478
                    $entryObject,
479
                    $resourceStreamInfo,
480
                    $context
481
                );
482
483
                $nuLink = new ODataMediaLink($streamTitle, $readUri, $readUri, $mediaContentType, $eTag);
484
                $mediaLinks[] = $nuLink;
485
            }
486
        }
487
        return [$mediaLink, $mediaLinks];
488
    }
489
490
    /**
491
     * Gets collection of projection nodes under the current node.
492
     *
493
     * @return ProjectionNode[]|ExpandedProjectionNode[]|null List of nodes
494
     *                                                        describing projections for the current segment, If this method returns
495
     *                                                        null it means no projections are to be applied and the entire resource
496
     *                                                        for the current segment should be serialized, If it returns non-null
497
     *                                                        only the properties described by the returned projection segments should
498
     *                                                        be serialized
499
     */
500
    protected function getProjectionNodes()
501
    {
502
        $expandedProjectionNode = $this->getCurrentExpandedProjectionNode();
503
        if (is_null($expandedProjectionNode) || $expandedProjectionNode->canSelectAllProperties()) {
504
            return null;
505
        }
506
507
        return $expandedProjectionNode->getChildNodes();
508
    }
509
510
    /**
511
     * Find a 'ExpandedProjectionNode' instance in the projection tree
512
     * which describes the current segment.
513
     *
514
     * @return ExpandedProjectionNode|null
515
     */
516
    protected function getCurrentExpandedProjectionNode()
517
    {
518
        $expandedProjectionNode = $this->getRequest()->getRootProjectionNode();
519
        if (is_null($expandedProjectionNode)) {
520
            return null;
521
        } else {
522
            $segmentNames = $this->getStack()->getSegmentNames();
523
            $depth = count($segmentNames);
524
            // $depth == 1 means serialization of root entry
525
            //(the resource identified by resource path) is going on,
526
            //so control won't get into the below for loop.
527
            //we will directly return the root node,
528
            //which is 'ExpandedProjectionNode'
529
            // for resource identified by resource path.
530
            if (0 != $depth) {
531
                for ($i = 1; $i < $depth; ++$i) {
532
                    $expandedProjectionNode = $expandedProjectionNode->findNode($segmentNames[$i]);
533
                    assert(!is_null($expandedProjectionNode), 'is_null($expandedProjectionNode)');
534
                    assert(
535
                        $expandedProjectionNode instanceof ExpandedProjectionNode,
536
                        '$expandedProjectionNode not instanceof ExpandedProjectionNode'
537
                    );
538
                }
539
            }
540
        }
541
542
        return $expandedProjectionNode;
543
    }
544
545
    /**
546
     * Check whether to expand a navigation property or not.
547
     *
548
     * @param string $navigationPropertyName Name of naviagtion property in question
549
     *
550
     * @return bool True if the given navigation should be
551
     *              explanded otherwise false
552
     */
553
    protected function shouldExpandSegment($navigationPropertyName)
554
    {
555
        $expandedProjectionNode = $this->getCurrentExpandedProjectionNode();
556
        if (is_null($expandedProjectionNode)) {
557
            return false;
558
        }
559
560
        $expandedProjectionNode = $expandedProjectionNode->findNode($navigationPropertyName);
561
562
        // null is a valid input to an instanceof call as of PHP 5.6 - will always return false
563
        return $expandedProjectionNode instanceof ExpandedProjectionNode;
564
    }
565
566
    /**
567
     * Wheter next link is needed for the current resource set (feed)
568
     * being serialized.
569
     *
570
     * @param int $resultSetCount Number of entries in the current
571
     *                            resource set
572
     *
573
     * @return bool true if the feed must have a next page link
574
     */
575
    protected function needNextPageLink($resultSetCount)
576
    {
577
        $currentResourceSet = $this->getCurrentResourceSetWrapper();
578
        $recursionLevel = count($this->getStack()->getSegmentNames());
579
        //$this->assert($recursionLevel != 0, '$recursionLevel != 0');
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% 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...
580
        $pageSize = $currentResourceSet->getResourceSetPageSize();
581
582
        if (1 == $recursionLevel) {
583
            //presence of $top option affect next link for root container
584
            $topValueCount = $this->getRequest()->getTopOptionCount();
585
            if (!is_null($topValueCount) && ($topValueCount <= $pageSize)) {
586
                return false;
587
            }
588
        }
589
        return $resultSetCount == $pageSize;
590
    }
591
592
    /**
593
     * Resource set wrapper for the resource being serialized.
594
     *
595
     * @return ResourceSetWrapper
596
     */
597
    protected function getCurrentResourceSetWrapper()
598
    {
599
        $segmentWrappers = $this->getStack()->getSegmentWrappers();
600
        $count = count($segmentWrappers);
601
602
        return 0 == $count ? $this->getRequest()->getTargetResourceSetWrapper() : $segmentWrappers[$count - 1];
603
    }
604
605
    /**
606
     * Get next page link from the given entity instance.
607
     *
608
     * @param mixed  &$lastObject Last object serialized to be
609
     *                            used for generating $skiptoken
610
     * @param string $absoluteUri Absolute response URI
611
     *
612
     * @return string for the link for next page
613
     */
614
    protected function getNextLinkUri(&$lastObject, $absoluteUri)
0 ignored issues
show
Unused Code introduced by
The parameter $absoluteUri is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
615
    {
616
        $currentExpandedProjectionNode = $this->getCurrentExpandedProjectionNode();
617
        $internalOrderByInfo = $currentExpandedProjectionNode->getInternalOrderByInfo();
618
        $skipToken = $internalOrderByInfo->buildSkipTokenValue($lastObject);
619
        assert(!is_null($skipToken), '!is_null($skipToken)');
620
        $skipToken = '?$skip='.$skipToken;
621
        return $skipToken;
622
    }
623
}
624