/** * Build nextpage link from the given object which will be the last object * in the page. * * @param mixed $lastObject Entity instance to build next page link from. * * @return string * * @throws ODataException If reflection exception occurs while accessing * property. */ public function buildNextPageLink($lastObject) { $nextPageLink = null; foreach ($this->_internalOrderByInfo->getOrderByPathSegments() as $orderByPathSegment) { $index = 0; $currentObject = $lastObject; $subPathSegments = $orderByPathSegment->getSubPathSegments(); $subPathCount = count($subPathSegments); foreach ($subPathSegments as &$subPathSegment) { $isLastSegment = $index == $subPathCount - 1; try { $dummyProperty = new \ReflectionProperty($currentObject, $subPathSegment->getName()); $currentObject = $dummyProperty->getValue($currentObject); if (is_null($currentObject)) { $nextPageLink .= 'null, '; break; } else { if ($isLastSegment) { $type = $subPathSegment->getInstanceType(); $value = $type->convertToOData($currentObject); $nextPageLink .= $value . ', '; } } } catch (\ReflectionException $reflectionException) { throw ODataException::createInternalServerError(Messages::internalSkipTokenInfoFailedToAccessOrInitializeProperty($subPathSegment->getName())); } $index++; } } return rtrim($nextPageLink, ", "); }
/** * Parse the given skiptoken, validate it using the given InternalOrderByInfo * and generates instance of InternalSkipTokenInfo. * * @param ResourceType &$resourceType The resource type of the * resource targetted by the * resource path. * @param InternalOrderByInfo &$internalOrderByInfo The $orderby details. * @param string $skipToken The $skiptoken value. * * @return InternalSkipTokenInfo * * @throws ODataException */ public static function parseSkipTokenClause(ResourceType &$resourceType, InternalOrderByInfo &$internalOrderByInfo, $skipToken) { $tokenValueDescriptor = null; if (!KeyDescriptor::tryParseValuesFromSkipToken($skipToken, $tokenValueDescriptor)) { ODataException::createSyntaxError(Messages::skipTokenParserSyntaxError($skipToken)); } $orderByPathSegments = null; //$positionalValues are of type array(int, array(string, IType)) $positionalValues =& $tokenValueDescriptor->getPositionalValuesByRef(); $count = count($positionalValues); $orderByPathSegments = $internalOrderByInfo->getOrderByPathSegments(); $orderByPathCount = count($orderByPathSegments); if ($count != $orderByPathCount) { ODataException::createBadRequestError(Messages::skipTokenParserSkipTokenNotMatchingOrdering($count, $skipToken, $orderByPathCount)); } $i = 0; foreach ($orderByPathSegments as $orderByPathSegment) { $typeProvidedInSkipToken = $positionalValues[$i][1]; if (!$typeProvidedInSkipToken instanceof Null1) { $orderBySubPathSegments = $orderByPathSegment->getSubPathSegments(); $j = count($orderBySubPathSegments) - 1; $expectedType = $orderBySubPathSegments[$j]->getInstanceType(); if (!$expectedType->isCompatibleWith($typeProvidedInSkipToken)) { ODataException::createSyntaxError(Messages::skipTokenParserInCompatibleTypeAtPosition($skipToken, $expectedType->getFullTypeName(), $i, $typeProvidedInSkipToken->getFullTypeName())); } } $i++; } return new InternalSkipTokenInfo($internalOrderByInfo, $positionalValues, $resourceType); }