/**
  * Process the given request Uri and creates an instance of 
  * RequestDescription from the processed uri.
  * 
  * @param Url         &$absoluteRequestUri The absolute request uri.
  * @param DataService &$dataService        Reference to the data service
  *                                         instance.
  * 
  * @return RequestDescription
  * 
  * @throws ODataException If any exception occurs while processing the segments
  *                        or incase of any version incompatibility.
  */
 public static function process(Url &$absoluteRequestUri, DataService &$dataService)
 {
     $absoluteRequestUri = $dataService->getHost()->getAbsoluteRequestUri();
     $absoluteServiceUri = $dataService->getHost()->getAbsoluteServiceUri();
     $requestUriSegments = array_slice($absoluteRequestUri->getSegments(), $absoluteServiceUri->getSegmentCount());
     $segmentDescriptors = null;
     try {
         $segmentDescriptors = SegmentParser::parseRequestUriSegements($requestUriSegments, $dataService->getMetadataQueryProviderWrapper(), true);
     } catch (ODataException $odataException) {
         throw $odataException;
     }
     $requestDescription = new RequestDescription($segmentDescriptors, $absoluteRequestUri);
     $requestTargetKind = $requestDescription->getTargetKind();
     if ($requestTargetKind != RequestTargetKind::METADATA && $requestTargetKind != RequestTargetKind::BATCH && $requestTargetKind != RequestTargetKind::SERVICE_DIRECTORY) {
         if ($requestTargetKind != RequestTargetKind::PRIMITIVE_VALUE && $requestTargetKind != RequestTargetKind::MEDIA_RESOURCE) {
             $requestDescription->setContainerName($requestDescription->getIdentifier());
         } else {
             // http://odata/NW.svc/Orders/$count
             // http://odata/NW.svc/Orders(123)/Customer/CustomerID/$value
             // http://odata/NW.svc/Employees(1)/$value
             // http://odata/NW.svc/Employees(1)/ThumbNail_48X48/$value
             $requestDescription->setContainerName($segmentDescriptors[count($segmentDescriptors) - 2]->getIdentifier());
         }
         if ($requestDescription->getIdentifier() === ODataConstants::URI_COUNT_SEGMENT) {
             if (!$dataService->getServiceConfiguration()->getAcceptCountRequests()) {
                 ODataException::createBadRequestError(Messages::dataServiceConfigurationCountNotAccepted());
             }
             $requestDescription->setRequestCountOption(RequestCountOption::VALUE_ONLY);
             // use of $count requires request DataServiceVersion
             // and MaxDataServiceVersion
             // greater than or equal to 2.0
             $requestDescription->raiseResponseVersion(2, 0, $dataService);
             $requestDescription->raiseMinimumVersionRequirement(2, 0, $dataService);
         } else {
             if ($requestDescription->isNamedStream()) {
                 $requestDescription->raiseMinimumVersionRequirement(3, 0, $dataService);
             } else {
                 if ($requestDescription->getTargetKind() == RequestTargetKind::RESOURCE) {
                     if (!$requestDescription->isLinkUri()) {
                         $resourceSetWrapper = $requestDescription->getTargetResourceSetWrapper();
                         //assert($resourceSetWrapper != null)
                         $hasNamedStream = $resourceSetWrapper->hasNamedStreams($dataService->getMetadataQueryProviderWrapper());
                         $hasBagProperty = $resourceSetWrapper->hasBagProperty($dataService->getMetadataQueryProviderWrapper());
                         if ($hasNamedStream || $hasBagProperty) {
                             $requestDescription->raiseResponseVersion(3, 0, $dataService);
                         }
                     }
                 } else {
                     if ($requestDescription->getTargetKind() == RequestTargetKind::BAG) {
                         $requestDescription->raiseResponseVersion(3, 0, $dataService);
                     }
                 }
             }
         }
     }
     return $requestDescription;
 }
예제 #2
0
 /**
  * To check whether the the query options $select, $expand
  * is applicable for the current requested resource.
  * 
  * @param string $queryItem The query option to check.
  * 
  * @return void
  * 
  * @throws ODataException Throws bad request error if the query 
  *                        options $select, $expand cannot be 
  *                        applied to the requested resource. 
  */
 private function _checkExpandOrSelectApplicable($queryItem)
 {
     if (!$this->_expandSelectApplicable) {
         ODataException::createBadRequestError(Messages::queryProcessorSelectOrExpandOptionNotApplicable($queryItem));
     }
 }
예제 #3
0
 /**
  * Create SegmentDescriptor for the first segment
  * 
  * @param string  $segmentIdentifier The identifier part of the 
  *                                   first segment
  * @param string  $keyPredicate      The predicate part of the first
  *                                   segment if any else NULL     
  * @param boolean $checkRights       Whether to check the rights on 
  *                                   this segment
  * 
  * @return SegmentDescriptor Descriptor for the first segment
  * 
  * @throws ODataException Exception if any validation fails
  */
 private function _createFirstSegmentDescriptor($segmentIdentifier, $keyPredicate, $checkRights)
 {
     $descriptor = new SegmentDescriptor();
     $descriptor->setIdentifier($segmentIdentifier);
     if ($segmentIdentifier === ODataConstants::URI_METADATA_SEGMENT) {
         $this->_assertion(is_null($keyPredicate));
         $descriptor->setTargetKind(RequestTargetKind::METADATA);
         return $descriptor;
     }
     if ($segmentIdentifier === ODataConstants::URI_BATCH_SEGMENT) {
         $this->_assertion(is_null($keyPredicate));
         $descriptor->setTargetKind(RequestTargetKind::BATCH);
         return $descriptor;
     }
     if ($segmentIdentifier === ODataConstants::URI_COUNT_SEGMENT) {
         ODataException::createBadRequestError(Messages::segmentParserSegmentNotAllowedOnRoot(ODataConstants::URI_COUNT_SEGMENT));
     }
     if ($segmentIdentifier === ODataConstants::URI_LINK_SEGMENT) {
         ODataException::createBadRequestError(Messages::segmentParserSegmentNotAllowedOnRoot(ODataConstants::URI_LINK_SEGMENT));
     }
     $resourceSetWrapper = $this->_providerWrapper->resolveResourceSet($segmentIdentifier);
     if ($resourceSetWrapper === null) {
         ODataException::createResourceNotFoundError($segmentIdentifier);
     }
     $descriptor->setTargetResourceSetWrapper($resourceSetWrapper);
     $descriptor->setTargetResourceType($resourceSetWrapper->getResourceType());
     $descriptor->setTargetSource(RequestTargetSource::ENTITY_SET);
     $descriptor->setTargetKind(RequestTargetKind::RESOURCE);
     if ($keyPredicate !== null) {
         $keyDescriptor = $this->_createKeyDescriptor($segmentIdentifier . '(' . $keyPredicate . ')', $resourceSetWrapper->getResourceType(), $keyPredicate);
         $descriptor->setKeyDescriptor($keyDescriptor);
         if (!$keyDescriptor->isEmpty()) {
             $descriptor->setSingleResult(true);
         }
     }
     if ($checkRights) {
         $resourceSetWrapper->checkResourceSetRightsForRead($descriptor->isSingleResult());
     }
     return $descriptor;
 }
예제 #4
0
 /**
  * For the given entry object compare it's eTag (if it has eTag properties)
  * with current eTag request headers (if it present).
  * 
  * @param mixed        &$entryObject             entity resource for which etag 
  *                                               needs to be checked.
  * @param ResourceType &$resourceType            Resource type of the entry 
  *                                               object.
  * @param boolean      &$needToSerializeResponse On return, this will contain 
  *                                               True if response needs to be
  *                                               serialized, False otherwise.
  *                                              
  * @return string/NULL The ETag for the entry object if it has eTag properties 
  *                     NULL otherwise.
  */
 protected function compareETag(&$entryObject, ResourceType &$resourceType, &$needToSerializeResponse)
 {
     $needToSerializeResponse = true;
     $eTag = null;
     $ifMatch = $this->_dataServiceHost->getRequestIfMatch();
     $ifNoneMatch = $this->_dataServiceHost->getRequestIfNoneMatch();
     if (is_null($entryObject)) {
         if (!is_null($ifMatch)) {
             ODataException::createPreConditionFailedError(Messages::dataServiceETagNotAllowedForNonExistingResource());
         }
         return null;
     }
     if ($this->_dataServiceConfiguration->getValidateETagHeader() && !$resourceType->hasETagProperties()) {
         if (!is_null($ifMatch) || !is_null($ifNoneMatch)) {
             // No eTag properties but request has eTag headers, bad request
             ODataException::createBadRequestError(Messages::dataServiceNoETagPropertiesForType());
         }
         // We need write the response but no eTag header
         return null;
     }
     if (!$this->_dataServiceConfiguration->getValidateETagHeader()) {
         // Configuration says do not validate ETag so we will not write ETag header in the
         // response even though the requested resource support it
         return null;
     }
     if (is_null($ifMatch) && is_null($ifNoneMatch)) {
         // No request eTag header, we need to write the response
         // and eTag header
     } else {
         if (strcmp($ifMatch, '*') == 0) {
             // If-Match:* => we need to write the response and eTag header
         } else {
             if (strcmp($ifNoneMatch, '*') == 0) {
                 // if-None-Match:* => Do not write the response (304 not modified),
                 // but write eTag header
                 $needToSerializeResponse = false;
             } else {
                 $eTag = $this->getETagForEntry($entryObject, $resourceType);
                 // Note: The following code for attaching the prefix W\"
                 // and the suffix " can be done in getETagForEntry function
                 // but that is causing an issue in Linux env where the
                 // firefix browser is unable to parse the ETag in this case.
                 // Need to follow up PHP core devs for this.
                 $eTag = ODataConstants::HTTP_WEAK_ETAG_PREFIX . $eTag . '"';
                 if (!is_null($ifMatch)) {
                     if (strcmp($eTag, $ifMatch) != 0) {
                         // Requested If-Match value does not match with current
                         // eTag Value then pre-condition error
                         // http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
                         ODataException::createPreConditionFailedError(Messages::dataServiceETagValueDoesNotMatch());
                     }
                 } else {
                     if (strcmp($eTag, $ifNoneMatch) == 0) {
                         //304 not modified, but in write eTag header
                         $needToSerializeResponse = false;
                     }
                 }
             }
         }
     }
     if (is_null($eTag)) {
         $eTag = $this->getETagForEntry($entryObject, $resourceType);
         // Note: The following code for attaching the prefix W\"
         // and the suffix " can be done in getETagForEntry function
         // but that is causing an issue in Linux env where the
         // firefix browser is unable to parse the ETag in this case.
         // Need to follow up PHP core devs for this.
         $eTag = ODataConstants::HTTP_WEAK_ETAG_PREFIX . $eTag . '"';
     }
     return $eTag;
 }
예제 #5
0
 /**
  * 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);
 }
예제 #6
0
 /**
  * Modify the 'Projection Tree' to include selection details
  * 
  * @param array(array(string)) $selectPathSegments Collection of select 
  *                                                 paths.
  * 
  * @return void
  * 
  * @throws ODataException If any error occurs while processing select
  *                        path segments
  */
 private function _applySelectionToProjectionTree($selectPathSegments)
 {
     foreach ($selectPathSegments as $selectSubPathSegments) {
         $currentNode = $this->_rootProjectionNode;
         $subPathCount = count($selectSubPathSegments);
         foreach ($selectSubPathSegments as $index => $selectSubPathSegment) {
             if (!$currentNode instanceof RootProjectionNode && !$currentNode instanceof ExpandedProjectionNode) {
                 ODataException::createBadRequestError(Messages::expandProjectionParserPropertyWithoutMatchingExpand($currentNode->getPropertyName()));
             }
             $currentNode->setSelectionFound();
             $isLastSegment = $index == $subPathCount - 1;
             if ($selectSubPathSegment === '*') {
                 $currentNode->setSelectAllImmediateProperties();
                 break;
             }
             $currentResourceType = $currentNode->getResourceType();
             $resourceProperty = $currentResourceType->tryResolvePropertyTypeByName($selectSubPathSegment);
             if (is_null($resourceProperty)) {
                 ODataException::createSyntaxError(Messages::expandProjectionParserPropertyNotFound($currentResourceType->getFullName(), $selectSubPathSegment, true));
             }
             if (!$isLastSegment) {
                 if ($resourceProperty->isKindOf(ResourcePropertyKind::BAG)) {
                     ODataException::createBadRequestError(Messages::expandProjectionParserBagPropertyAsInnerSelectSegment($currentResourceType->getFullName(), $selectSubPathSegment));
                 } else {
                     if ($resourceProperty->isKindOf(ResourcePropertyKind::PRIMITIVE)) {
                         ODataException::createBadRequestError(Messages::expandProjectionParserPrimitivePropertyUsedAsNavigationProperty($currentResourceType->getFullName(), $selectSubPathSegment));
                     } else {
                         if ($resourceProperty->isKindOf(ResourcePropertyKind::COMPLEX_TYPE)) {
                             ODataException::createBadRequestError(Messages::expandProjectionParserComplexPropertyAsInnerSelectSegment($currentResourceType->getFullName(), $selectSubPathSegment));
                         } else {
                             if ($resourceProperty->getKind() != ResourcePropertyKind::RESOURCE_REFERENCE && $resourceProperty->getKind() != ResourcePropertyKind::RESOURCESET_REFERENCE) {
                                 ODataException::createInternalServerError(Messages::expandProjectionParserUnexpectedPropertyType());
                             }
                         }
                     }
                 }
             }
             $node = $currentNode->findNode($selectSubPathSegment);
             if (is_null($node)) {
                 if (!$isLastSegment) {
                     ODataException::createBadRequestError(Messages::expandProjectionParserPropertyWithoutMatchingExpand($selectSubPathSegment));
                 }
                 $node = new ProjectionNode($selectSubPathSegment, $resourceProperty);
                 $currentNode->addNode($node);
             }
             $currentNode = $node;
             if ($currentNode instanceof ExpandedProjectionNode && $isLastSegment) {
                 $currentNode->setSelectionFound();
                 $currentNode->markSubtreeAsSelected();
             }
         }
     }
 }
예제 #7
0
 /**
  * Validates the given version in string format and returns the version as instance of Version
  * 
  * @param string $versionHeader The DataServiceVersion or MaxDataServiceVersion header value
  * @param string $headerName    The name of the header
  * 
  * @return Version
  * 
  * @throws ODataException If the version is malformed or not supported
  */
 private static function _validateAndGetVersion($versionHeader, $headerName)
 {
     $libName = null;
     $versionHeader = trim($versionHeader);
     $libNameIndex = strpos($versionHeader, ';');
     if ($libNameIndex !== false) {
         $libName = substr($versionHeader, $libNameIndex);
     } else {
         $libNameIndex = strlen($versionHeader);
     }
     $dotIndex = -1;
     for ($i = 0; $i < $libNameIndex; $i++) {
         if ($versionHeader[$i] == '.') {
             if ($dotIndex != -1) {
                 ODataException::createBadRequestError(Messages::requestDescriptionInvalidVersionHeader($versionHeader, $headerName));
             }
             $dotIndex = $i;
         } else {
             if ($versionHeader[$i] < '0' || $versionHeader[$i] > '9') {
                 ODataException::createBadRequestError(Messages::requestDescriptionInvalidVersionHeader($versionHeader, $headerName));
             }
         }
     }
     $major = $minor = 0;
     if ($dotIndex != -1) {
         if ($dotIndex == 0) {
             ODataException::createBadRequestError(Messages::requestDescriptionInvalidVersionHeader($versionHeader, $headerName));
         }
         $major = intval(substr($versionHeader, 0, $dotIndex));
         $minor = intval(substr($versionHeader, $dotIndex + 1, $libNameIndex));
     } else {
         $major = intval(substr($versionHeader, 0, $dotIndex));
         $minor = 0;
     }
     $version = new Version($major, $minor);
     $isSupportedVersion = false;
     foreach (self::getKnownDataServiceVersions() as $version1) {
         if ($version->compare($version1) == 0) {
             $isSupportedVersion = true;
             break;
         }
     }
     if (!$isSupportedVersion) {
         $availableVersions = null;
         foreach (self::getKnownDataServiceVersions() as $version1) {
             $availableVersions .= $version1->toString() . ', ';
         }
         $availableVersions = rtrim($availableVersions, ', ');
         ODataException::createBadRequestError(Messages::requestDescriptionUnSupportedVersion($headerName, $versionHeader, $availableVersions));
     }
     return $version;
 }
예제 #8
0
 /**
  * Build 'OrderBy Tree' from the given orderby path segments, also build 
  * comparsion function for each path segment.
  * 
  * @param array(array) &$ordeyByPathSegments Collection of orderby path segments,
  *                                           this is passed by reference
  *                                           since we need this function to 
  *                                           modify this array in two cases:
  *                                           1. if asc or desc present, then the 
  *                                              corrosponding sub path segment 
  *                                              should be removed
  *                                           2. remove duplicate orderby path 
  *                                              segment
  * 
  * @return void
  * 
  * @throws ODataException If any error occurs while processing the orderby path 
  *                        segments
  */
 private function _buildOrderByTree(&$ordeyByPathSegments)
 {
     foreach ($ordeyByPathSegments as $index1 => &$ordeyBySubPathSegments) {
         $currentNode = $this->_rootOrderByNode;
         $currentObject = $this->_dummyObject;
         $ascending = true;
         $subPathCount = count($ordeyBySubPathSegments);
         // Check sort order is specified in the path, if so set a
         // flag and remove that segment
         if ($subPathCount > 1) {
             if ($ordeyBySubPathSegments[$subPathCount - 1] === '*desc') {
                 $ascending = false;
                 unset($ordeyBySubPathSegments[$subPathCount - 1]);
                 $subPathCount--;
             } else {
                 if ($ordeyBySubPathSegments[$subPathCount - 1] === '*asc') {
                     unset($ordeyBySubPathSegments[$subPathCount - 1]);
                     $subPathCount--;
                 }
             }
         }
         $ancestors = array($this->_rootOrderByNode->getResourceSetWrapper()->getName());
         foreach ($ordeyBySubPathSegments as $index2 => $orderBySubPathSegment) {
             $isLastSegment = $index2 == $subPathCount - 1;
             $resourceSetWrapper = null;
             $resourceType = $currentNode->getResourceType();
             $resourceProperty = $resourceType->tryResolvePropertyTypeByName($orderBySubPathSegment);
             if (is_null($resourceProperty)) {
                 ODataException::createSyntaxError(Messages::orderByParserPropertyNotFound($resourceType->getFullName(), $orderBySubPathSegment));
             }
             if ($resourceProperty->isKindOf(ResourcePropertyKind::BAG)) {
                 ODataException::createBadRequestError(Messages::orderByParserBagPropertyNotAllowed($resourceProperty->getName()));
             } else {
                 if ($resourceProperty->isKindOf(ResourcePropertyKind::PRIMITIVE)) {
                     if (!$isLastSegment) {
                         ODataException::createBadRequestError(Messages::orderByParserPrimitiveAsIntermediateSegment($resourceProperty->getName()));
                     }
                     $type = $resourceProperty->getInstanceType();
                     if ($type instanceof Binary) {
                         ODataException::createBadRequestError(Messages::orderbyParserSortByBinaryPropertyNotAllowed($resourceProperty->getName()));
                     }
                 } else {
                     if ($resourceProperty->getKind() == ResourcePropertyKind::RESOURCESET_REFERENCE || $resourceProperty->getKind() == ResourcePropertyKind::RESOURCE_REFERENCE) {
                         $this->_assertion($currentNode instanceof OrderByRootNode || $currentNode instanceof OrderByNode);
                         $resourceSetWrapper = $currentNode->getResourceSetWrapper();
                         $this->_assertion(!is_null($resourceSetWrapper));
                         $resourceSetWrapper = $this->_providerWrapper->getResourceSetWrapperForNavigationProperty($resourceSetWrapper, $resourceType, $resourceProperty);
                         if (is_null($resourceSetWrapper)) {
                             ODataException::createBadRequestError(Messages::badRequestInvalidPropertyNameSpecified($resourceType->getFullName(), $orderBySubPathSegment));
                         }
                         if ($resourceProperty->getKind() == ResourcePropertyKind::RESOURCESET_REFERENCE) {
                             ODataException::createBadRequestError(Messages::orderbyParserResourceSetReferenceNotAllowed($resourceProperty->getName(), $resourceType->getFullName()));
                         }
                         $resourceSetWrapper->checkResourceSetRightsForRead(true);
                         if ($isLastSegment) {
                             ODataException::createBadRequestError(Messages::orderByParserSortByNavigationPropertyIsNotAllowed($resourceProperty->getName()));
                         }
                         $ancestors[] = $orderBySubPathSegment;
                     } else {
                         if ($resourceProperty->isKindOf(ResourcePropertyKind::COMPLEX_TYPE)) {
                             if ($isLastSegment) {
                                 ODataException::createBadRequestError(Messages::orderByParserSortByComplexPropertyIsNotAllowed($resourceProperty->getName()));
                             }
                             $ancestors[] = $orderBySubPathSegment;
                         } else {
                             ODataException::createInternalServerError(Messages::orderByParserUnexpectedPropertyType());
                         }
                     }
                 }
             }
             $node = $currentNode->findNode($orderBySubPathSegment);
             if (is_null($node)) {
                 if ($resourceProperty->isKindOf(ResourcePropertyKind::PRIMITIVE)) {
                     $node = new OrderByLeafNode($orderBySubPathSegment, $resourceProperty, $ascending);
                     $this->_comparisonFunctions[] = $node->buildComparisonFunction($ancestors);
                 } else {
                     if ($resourceProperty->getKind() == ResourcePropertyKind::RESOURCE_REFERENCE) {
                         $node = new OrderByNode($orderBySubPathSegment, $resourceProperty, $resourceSetWrapper);
                         // Initialize this member variable (identified by
                         // $resourceProperty) of parent object.
                         try {
                             $dummyProperty = new \ReflectionProperty($currentObject, $resourceProperty->getName());
                             $object = $resourceProperty->getInstanceType()->newInstance();
                             $dummyProperty->setValue($currentObject, $object);
                             $currentObject = $object;
                         } catch (\ReflectionException $reflectionException) {
                             throw ODataException::createInternalServerError(Messages::orderByParserFailedToAccessOrInitializeProperty($resourceProperty->getName(), $resourceType->getName()));
                         }
                     } else {
                         if ($resourceProperty->getKind() == ResourcePropertyKind::COMPLEX_TYPE) {
                             $node = new OrderByNode($orderBySubPathSegment, $resourceProperty, null);
                             // Initialize this member variable
                             // (identified by $resourceProperty)of parent object.
                             try {
                                 $dummyProperty = new \ReflectionProperty($currentObject, $resourceProperty->getName());
                                 $object = $resourceProperty->getInstanceType()->newInstance();
                                 $dummyProperty->setValue($currentObject, $object);
                                 $currentObject = $object;
                             } catch (\ReflectionException $reflectionException) {
                                 throw ODataException::createInternalServerError(Messages::orderByParserFailedToAccessOrInitializeProperty($resourceProperty->getName(), $resourceType->getName()));
                             }
                         }
                     }
                 }
                 $currentNode->addNode($node);
             } else {
                 try {
                     $dummyProperty = new \ReflectionProperty($currentObject, $resourceProperty->getName());
                     $currentObject = $dummyProperty->getValue($currentObject);
                 } catch (\ReflectionException $reflectionException) {
                     throw ODataException::createInternalServerError(Messages::orderByParserFailedToAccessOrInitializeProperty($resourceProperty->getName(), $resourceType->getName()));
                 }
                 if ($node instanceof OrderByLeafNode) {
                     //remove duplicate orderby path
                     unset($ordeyByPathSegments[$index1]);
                 }
             }
             $currentNode = $node;
         }
     }
 }
예제 #9
0
 /**
  * This method verfiy the client provided url query parameters and check whether
  * any of the odata query option specified more than once or check any of the 
  * non-odata query parameter start will $ symbol or check any of the odata query 
  * option specified with out value. If any of the above check fails throws 
  * ODataException, else set _queryOptions memeber variable
  * 
  * @return void
  * 
  * @throws ODataException
  */
 public function validateQueryParameters()
 {
     $queryOptions =& $this->_operationContext->incomingRequest()->getQueryParameters();
     reset($queryOptions);
     // Check whether user specified $format query option
     while ($queryOption = current($queryOptions)) {
         $optionName = key($queryOption);
         $optionValue = current($queryOption);
         if (!empty($optionName) && $optionName === ODataConstants::HTTPQUERY_STRING_FORMAT) {
             //$optionValue is the format
             if (!is_null($optionValue)) {
                 if ($optionValue === ODataConstants::FORMAT_ATOM) {
                     $this->setRequestAccept(ODataConstants::MIME_APPLICATION_ATOM . ';q=1.0');
                 } else {
                     if ($optionValue === ODataConstants::FORMAT_JSON) {
                         $this->setRequestAccept(ODataConstants::MIME_APPLICATION_JSON . ';q=1.0');
                     } else {
                         // Invalid format value, this error should not be
                         // serialized in atom or json format since we don't
                         // know which format client can understand, so error
                         // will be in plain text.
                         header(ODataConstants::HTTPRESPONSE_HEADER_CONTENTTYPE . ':' . ODataConstants::MIME_TEXTPLAIN);
                         header(ODataConstants::HTTPRESPONSE_HEADER_STATUS . ':' . HttpStatus::CODE_BAD_REQUEST . ' ' . 'Bad Request');
                         echo Messages::queryProcessorInvalidValueForFormat();
                         exit;
                     }
                 }
             }
             break;
         }
         next($queryOptions);
     }
     reset($queryOptions);
     $namesFound = array();
     while ($queryOption = current($queryOptions)) {
         $optionName = key($queryOption);
         $optionValue = current($queryOption);
         if (empty($optionName)) {
             if (!empty($optionValue)) {
                 if ($optionValue[0] == '$') {
                     if ($this->_isODataQueryOption($optionValue)) {
                         ODataException::createBadRequestError(Messages::dataServiceHostODataQueryOptionFoundWithoutValue($optionValue));
                     } else {
                         ODataException::createBadRequestError(Messages::dataServiceHostNonODataOptionBeginsWithSystemCharacter($optionValue));
                     }
                 }
             }
         } else {
             if ($optionName[0] == '$') {
                 if (!$this->_isODataQueryOption($optionName)) {
                     ODataException::createBadRequestError(Messages::dataServiceHostNonODataOptionBeginsWithSystemCharacter($optionName));
                 }
                 if (array_search($optionName, $namesFound) !== false) {
                     ODataException::createBadRequestError(Messages::dataServiceHostODataQueryOptionCannotBeSpecifiedMoreThanOnce($optionName));
                 }
                 if (empty($optionValue)) {
                     ODataException::createBadRequestError(Messages::dataServiceHostODataQueryOptionFoundWithoutValue($optionName));
                 }
                 $namesFound[] = $optionName;
             }
         }
         next($queryOptions);
     }
     $this->_queryOptions = $queryOptions;
 }