/**
  * If last sub path segment specified in the select clause does not appear in the prjection tree,
  * then parser will create 'ProjectionNode' for them
  */
 public function testPrjectionNodeCreation()
 {
     try {
         $northWindMetadata = CreateNorthWindMetadata3::Create();
         $queryProvider = new NorthWindQueryProvider2();
         $configuration = new DataServiceConfiguration($northWindMetadata);
         $configuration->setEntitySetAccessRule('*', EntitySetRights::ALL);
         $metaQueryProverWrapper = new MetadataQueryProviderWrapper($northWindMetadata, $queryProvider, $configuration, false);
         $ordersResourceSetWrapper = $metaQueryProverWrapper->resolveResourceSet('Orders');
         $orderResourceType = $ordersResourceSetWrapper->getResourceType();
         //test selection of properties which is not included in expand clause
         //1 primitve ('Order_Details/UnitPrice') and 1 link to navigation 'Customer'
         $projectionTreeRoot = ExpandProjectionParser::parseExpandAndSelectClause($ordersResourceSetWrapper, $orderResourceType, null, null, null, 'Order_Details', 'Order_Details/UnitPrice, Customer', $metaQueryProverWrapper);
         //expand option is absent
         $this->assertTrue($projectionTreeRoot->isExpansionSpecified());
         //select is applied
         $this->assertTrue($projectionTreeRoot->isSelectionSpecified());
         $this->assertFalse($projectionTreeRoot->canSelectAllImmediateProperties());
         $this->assertFalse($projectionTreeRoot->canSelectAllProperties());
         //there are 2 child nodes for the root
         $this->assertEquals(count($projectionTreeRoot->getChildNodes()), 2);
         //The child nodes one 'ProjectionNode' Customer and one 'ExpandedProjectionNode' for 'Order'
         $childNodes = $projectionTreeRoot->getChildNodes();
         $this->assertTrue(array_key_exists('Order_Details', $childNodes));
         $this->assertTrue(array_key_exists('Customer', $childNodes));
         $this->assertTrue($childNodes['Order_Details'] instanceof ExpandedProjectionNode);
         $this->assertTrue($childNodes['Customer'] instanceof ProjectionNode);
         //'Order_Detials' has a child node
         $childNodes = $childNodes['Order_Details']->getChildNodes();
         $this->assertEquals(count($childNodes), 1);
         $this->assertTrue(array_key_exists('UnitPrice', $childNodes));
         $this->assertTrue($childNodes['UnitPrice'] instanceof ProjectionNode);
     } catch (\Exception $exception) {
         $this->fail('An unexpected Exception has been raised' . $exception->getMessage());
     }
 }
예제 #2
0
 /**
  * Process the $expand and $select option and update the request description.
  * 
  * @return void
  * 
  * @throws ODataException Throws bad request error in the following cases
  *                          (1) If $expand or select cannot be applied to the
  *                              requested resource.
  *                          (2) If projection is disabled by the developer
  *                          (3) If some error occurs while parsing the options
  */
 private function _processExpandAndSelect()
 {
     $expand = $this->_dataService->getHost()->getQueryStringItem(ODataConstants::HTTPQUERY_STRING_EXPAND);
     if (!is_null($expand)) {
         $this->_checkExpandOrSelectApplicable(ODataConstants::HTTPQUERY_STRING_EXPAND);
     }
     $select = $this->_dataService->getHost()->getQueryStringItem(ODataConstants::HTTPQUERY_STRING_SELECT);
     if (!is_null($select)) {
         if (!$this->_dataService->getServiceConfiguration()->getAcceptProjectionRequests()) {
             ODataException::createBadRequestError(Messages::dataServiceConfigurationProjectionsNotAccepted());
         }
         $this->_checkExpandOrSelectApplicable(ODataConstants::HTTPQUERY_STRING_SELECT);
     }
     // We will generate RootProjectionNode in case of $link request also, but
     // expand and select in this case must be null (we are ensuring this above)
     // 'RootProjectionNode' is required while generating next page Link
     if ($this->_expandSelectApplicable || $this->_requestDescription->isLinkUri()) {
         try {
             $rootProjectionNode = ExpandProjectionParser::parseExpandAndSelectClause($this->_requestDescription->getTargetResourceSetWrapper(), $this->_requestDescription->getTargetResourceType(), $this->_requestDescription->getInternalOrderByInfo(), $this->_requestDescription->getSkipCount(), $this->_requestDescription->getTopCount(), $expand, $select, $this->_dataService->getMetadataQueryProviderWrapper());
             if ($rootProjectionNode->isSelectionSpecified()) {
                 $this->_requestDescription->raiseMinimumVersionRequirement(2, 0, $this->_dataService);
             }
             if ($rootProjectionNode->hasPagedExpandedResult()) {
                 $this->_requestDescription->raiseResponseVersion(2, 0, $this->_dataService);
             }
             $this->_requestDescription->setRootProjectionNode($rootProjectionNode);
         } catch (ODataException $odataException) {
             throw $odataException;
         }
     }
 }
 /**
  * One can expand a navigation property only if corrosponding resource set is visible
  * 
  */
 public function testExpandWithNonVisibleResourceSet()
 {
     try {
         $northWindMetadata = CreateNorthWindMetadata3::Create();
         $queryProvider = new NorthWindQueryProvider2();
         $configuration = new DataServiceConfiguration($northWindMetadata);
         //Make 'Customers' and 'Orders' visible, make 'Order_Details' invisible
         $configuration->setEntitySetAccessRule('Customers', EntitySetRights::ALL);
         $configuration->setEntitySetAccessRule('Orders', EntitySetRights::ALL);
         $metaQueryProverWrapper = new MetadataQueryProviderWrapper($northWindMetadata, $queryProvider, $configuration, false);
         $customersResourceSetWrapper = $metaQueryProverWrapper->resolveResourceSet('Customers');
         $customerResourceType = $customersResourceSetWrapper->getResourceType();
         $exceptionThrown = false;
         try {
             $projectionTree = ExpandProjectionParser::parseExpandAndSelectClause($customersResourceSetWrapper, $customerResourceType, null, null, null, 'Orders/Order_Details', null, $metaQueryProverWrapper);
         } catch (ODataException $odataException) {
             $exceptionThrown = true;
             $this->assertStringEndsWith("(Check the resource set of the navigation property 'Order_Details' is visible)", $odataException->getMessage());
         }
         if (!$exceptionThrown) {
             $this->fail('An expected ODataException for navigation to invisible resource set has not been thrown');
         }
     } catch (\Exception $exception) {
         $this->fail('An unexpected Exception has been raised' . $exception->getMessage());
     }
 }