/**
  * Get the Multiplicity of the relationship end
  * 
  * @return string
  */
 public function getMultiplicity()
 {
     if (!is_null($this->_fromProperty) && $this->_fromProperty->getKind() == ResourcePropertyKind::RESOURCE_REFERENCE) {
         return ODataConstants::ZERO_OR_ONE;
     }
     return ODataConstants::MANY;
 }
 public function testGetResourceAssociationSetEndIsNotVisible()
 {
     $fakePropName = "Fake Prop";
     Phockito::when($this->mockResourceProperty->getName())->return($fakePropName);
     Phockito::when($this->mockResourceType->resolvePropertyDeclaredOnThisType($fakePropName))->return($this->mockResourceProperty);
     $fakeTypeName = "Fake Type";
     Phockito::when($this->mockResourceType->getName())->return($fakeTypeName);
     $fakeSetName = "Fake Set";
     Phockito::when($this->mockResourceSet->getName())->return($fakeSetName);
     Phockito::when($this->mockResourceSet->getResourceType())->return($this->mockResourceType);
     Phockito::when($this->mockResourceSet2->getResourceType())->return($this->mockResourceType2);
     //Indicate the resource set is visible
     Phockito::when($this->mockServiceConfig->getEntitySetAccessRule($this->mockResourceSet))->return(EntitySetRights::READ_SINGLE);
     //Indicate the resource set is visible
     Phockito::when($this->mockServiceConfig->getEntitySetAccessRule($this->mockResourceSet2))->return(EntitySetRights::NONE);
     Phockito::when($this->mockMetadataProvider->getResourceAssociationSet($this->mockResourceSet, $this->mockResourceType, $this->mockResourceProperty))->return($this->mockResourceAssociationSet);
     Phockito::when($this->mockResourceAssociationSet->getResourceAssociationSetEnd($this->mockResourceSet, $this->mockResourceType, $this->mockResourceProperty))->return($this->mockResourceAssociationSetEnd);
     Phockito::when($this->mockResourceAssociationSet->getRelatedResourceAssociationSetEnd($this->mockResourceSet, $this->mockResourceType, $this->mockResourceProperty))->return($this->mockResourceAssociationSetEnd);
     Phockito::when($this->mockResourceAssociationSetEnd->getResourceSet())->return($this->mockResourceSet2);
     Phockito::when($this->mockResourceAssociationSetEnd->getResourceType())->return($this->mockResourceType2);
     $wrapper = $this->getMockedWrapper();
     $actual = $wrapper->getResourceAssociationSet($this->mockResourceSet, $this->mockResourceType, $this->mockResourceProperty);
     $this->assertNull($actual);
 }
 /**
  * Gets the ResourceAssociationType instance for the given 
  * ResourceAssociationSet and one of it's end.
  *       
  * This function first searches the ResourceAssociationType cache, 
  * if found return it otherwise create the Association type for the given 
  * association set, cache and return it.
  * 
  * Creation of ResourceAssociationType includes two sub-tasks:
  *  1. Deciding name of 'ResourceAssociationType' 
  *  (see the function _getAssociationTypeName)
  *  2. Deciding names for two 'ResourceAssociationTypeEnd' of the 
  *  'ResourceAssociationType'
  *  Refer ./AssociationSetAndTypeNamingRules.txt for naming rules.
  *   
  * @param ResourceAssociationSet $resourceAssociationSet Association set to get the association type
  * @param ResourceSetWrapper     $resourceSet            Resource set for one of the ends of given association set
  * @param ResourceType           $resourceType           Resource type for one of the ends of given association set
  * @param ResourceProperty       $navigationProperty     Resource property for one of the ends of given association set
  *
  * 
  * @return ResourceAssociationType The association type for the given association set
  *
  */
 private function _getResourceAssociationType(ResourceAssociationSet $resourceAssociationSet, ResourceSetWrapper $resourceSet, ResourceType $resourceType, ResourceProperty $navigationProperty)
 {
     $resourceTypeNamespace = $this->getResourceTypeNamespace($resourceType);
     $resourceAssociationTypesInNamespace =& $this->getResourceAssociationTypesForNamespace($resourceTypeNamespace);
     $associationTypeLookupKey = $resourceType->getName() . '_' . $navigationProperty->getName();
     if (array_key_exists($associationTypeLookupKey, $resourceAssociationTypesInNamespace)) {
         return $resourceAssociationTypesInNamespace[$associationTypeLookupKey];
     }
     //Generate resource association type end names
     //Refer ./AssociationSetAndTypeNamingRules.txt
     $associationTypeEnd1Name = $associationTypeEnd2Name = null;
     $isBiDirectional = $resourceAssociationSet->isBidirectional();
     if ($isBiDirectional) {
         $associationTypeEnd1Name = $resourceAssociationSet->getEnd1()->getResourceType()->getName() . '_' . $resourceAssociationSet->getEnd1()->getResourceProperty()->getName();
         $associationTypeEnd2Name = $resourceAssociationSet->getEnd2()->getResourceType()->getName() . '_' . $resourceAssociationSet->getEnd2()->getResourceProperty()->getName();
     } else {
         if (!is_null($resourceAssociationSet->getEnd1()->getResourceProperty())) {
             $associationTypeEnd1Name = $resourceAssociationSet->getEnd1()->getResourceType()->getName();
             $associationTypeEnd2Name = $resourceAssociationSet->getEnd1()->getResourceProperty()->getName();
         } else {
             $associationTypeEnd1Name = $resourceAssociationSet->getEnd2()->getResourceProperty()->getName();
             $associationTypeEnd2Name = $resourceAssociationSet->getEnd2()->getResourceType()->getName();
         }
     }
     //Generate resource association type name
     //Refer ./AssociationSetAndTypeNamingRules.txt
     $resourceAssociationTypeName = $this->_getAssociationTypeName($resourceAssociationSet);
     //Create and cache the association type
     $resourceAssociationType = new ResourceAssociationType($resourceAssociationTypeName, $resourceTypeNamespace, new ResourceAssociationTypeEnd($associationTypeEnd1Name, $resourceAssociationSet->getEnd1()->getResourceType(), $resourceAssociationSet->getEnd1()->getResourceProperty(), $resourceAssociationSet->getEnd2()->getResourceProperty()), new ResourceAssociationTypeEnd($associationTypeEnd2Name, $resourceAssociationSet->getEnd2()->getResourceType(), $resourceAssociationSet->getEnd2()->getResourceProperty(), $resourceAssociationSet->getEnd1()->getResourceProperty()));
     $resourceAssociationTypesInNamespace[$associationTypeLookupKey] = $resourceAssociationType;
     if ($isBiDirectional) {
         $relatedAssociationSetEnd = $resourceAssociationSet->getRelatedResourceAssociationSetEnd($resourceSet->getResourceSet(), $resourceType, $navigationProperty);
         $relatedEndLookupKey = $relatedAssociationSetEnd->getResourceType()->getName() . '_' . $relatedAssociationSetEnd->getResourceProperty()->getName();
         $resourceAssociationTypesInNamespace[$relatedEndLookupKey] = $resourceAssociationType;
     }
     return $resourceAssociationType;
 }
 /**
  * Get related resource for a resource
  * 
  * @param ResourceSet      $sourceResourceSet    The source resource set
  * @param mixed            $sourceEntityInstance The source resource
  * @param ResourceSet      $targetResourceSet    The resource set of 
  *                                               the navigation property
  * @param ResourceProperty $targetProperty       The navigation property to be 
  *                                               retrieved
  * 
  * @return object|null The related resource if exists else null
  */
 public function getRelatedResourceReference(ResourceSet $sourceResourceSet, $sourceEntityInstance, ResourceSet $targetResourceSet, ResourceProperty $targetProperty)
 {
     $result = null;
     $srcClass = get_class($sourceEntityInstance);
     $navigationPropName = $targetProperty->getName();
     if ($srcClass === 'Order') {
         if ($navigationPropName === 'Customer') {
             if (empty($sourceEntityInstance->CustomerID)) {
                 $result = null;
             } else {
                 $query = "SELECT * FROM Customers WHERE CustomerID = '{$sourceEntityInstance->CustomerID}'";
                 $stmt = sqlsrv_query($this->_connectionHandle, $query);
                 if ($stmt === false) {
                     $errorAsString = self::_getSQLSRVError();
                     throw ODataException::createInternalServerError($errorAsString);
                 }
                 if (!sqlsrv_has_rows($stmt)) {
                     $result = null;
                 }
                 $result = $this->_serializeCustomer(sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC));
             }
         } else {
             die('Customer does not have navigation porperty with name: ' . $navigationPropName);
         }
     } else {
         if ($srcClass === 'Order_Details') {
             if ($navigationPropName === 'Order') {
                 if (empty($sourceEntityInstance->OrderID)) {
                     $result = null;
                 } else {
                     $query = "SELECT * FROM Orders WHERE OrderID = {$sourceEntityInstance->OrderID}";
                     $stmt = sqlsrv_query($this->_connectionHandle, $query);
                     if ($stmt === false) {
                         $errorAsString = self::_getSQLSRVError();
                         throw ODataException::createInternalServerError($errorAsString);
                     }
                     if (!sqlsrv_has_rows($stmt)) {
                         $result = null;
                     }
                     $result = $this->_serializeOrder(sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC));
                 }
             } else {
                 die('Order_Details does not have navigation porperty with name: ' . $navigationPropName);
             }
         }
     }
     return $result;
 }
Exemple #5
0
 /**
  * Write primitive property facets. 
  * 
  * @param ResourceProperty $primitveProperty primitive property
  * 
  * @return void
  */
 private function _writePrimitivePropertyFacets(ResourceProperty $primitveProperty)
 {
     $nullable = true;
     if ($primitveProperty->isKindOf(ResourcePropertyKind::KEY)) {
         $nullable = false;
     }
     $this->_xmlWriter->writeAttribute(ODataConstants::NULLABLE, $nullable ? "true" : "false");
 }
 /**
  * Writes a primitive value and related information to the given
  * ODataProperty instance.
  * 
  * @param mixed            &$primitiveValue   The primitive value to write.
  * @param ResourceProperty &$resourceProperty The metadata of the primitive
  *                                            property value.
  * @param ODataProperty    &$odataProperty    ODataProperty instance to which
  *                                            the primitive value and related
  *                                            information to write out.
  *
  * @throws ODataException If given value is not primitive.
  * 
  * @return void
  */
 private function _writePrimitiveValue(&$primitiveValue, ResourceProperty &$resourceProperty, ODataProperty &$odataProperty)
 {
     if (is_object($primitiveValue)) {
         //TODO ERROR: The property 'PropertyName'
         //is defined as primitive type but value is an object
     }
     $odataProperty->name = $resourceProperty->getName();
     $odataProperty->typeName = $resourceProperty->getInstanceType()->getFullTypeName();
     if (is_null($primitiveValue)) {
         $odataProperty->value = null;
     } else {
         $resourceType = $resourceProperty->getResourceType();
         $this->_primitiveToString($resourceType, $primitiveValue, $odataProperty->value);
     }
 }
Exemple #7
0
 /**
  * Pushes a segment for the current navigation property being written out.
  * Note: Refer 'ObjectModelSerializerNotes.txt' for more details about
  * 'Segment Stack' and this method.
  * Note: Calls to this method should be balanced with calls to popSegment.
  *
  * @param ResourceProperty &$resourceProperty Current navigation property 
  *                                            being written out
  *
  * @return bool true if a segment was pushed, false otherwise
  *
  * @throws InvalidOperationException If this function invoked with non-navigation
  *                                   property instance.
  */
 private function _pushSegmentForNavigationProperty(ResourceProperty &$resourceProperty)
 {
     if ($resourceProperty->getTypeKind() == ResourceTypeKind::ENTITY) {
         $this->assert(!empty($this->_segmentNames), '!is_empty($this->_segmentNames');
         $currentResourceSetWrapper = $this->_getCurrentResourceSetWrapper();
         $currentResourceType = $currentResourceSetWrapper->getResourceType();
         $currentResourceSetWrapper = $this->service->getProvidersWrapper()->getResourceSetWrapperForNavigationProperty($currentResourceSetWrapper, $currentResourceType, $resourceProperty);
         $this->assert(!is_null($currentResourceSetWrapper), '!null($currentResourceSetWrapper)');
         return $this->_pushSegment($resourceProperty->getName(), $currentResourceSetWrapper);
     } else {
         throw new InvalidOperationException('pushSegmentForNavigationProperty should not be called with non-entity type');
     }
 }
 /**
  * Gets the ResourceAssociationSet instance for the given source 
  * association end.
  * 
  * @param ResourceSet      $sourceResourceSet      Resource set 
  *                                                 of the source
  *                                                 association end
  * @param ResourceType     $sourceResourceType     Resource type of the source
  *                                                 association end
  * @param ResourceProperty $targetResourceProperty Resource property of 
  *                                                 the source
  *                                                 association end
  * 
  * @return ResourceAssociationSet
  */
 public function getResourceAssociationSet(ResourceSet $sourceResourceSet, ResourceType $sourceResourceType, ResourceProperty $targetResourceProperty)
 {
     //e.g.
     //ResourceSet => Representing 'Customers' entity set
     //ResourceType => Representing'Customer' entity type
     //ResourceProperty => Representing 'Orders' property
     //We have created ResourceAssoicationSet while adding
     //ResourceSetReference or ResourceReference
     //and kept in $this->associationSets
     //$metadata->addResourceSetReferenceProperty(
     //             $customersEntityType,
     //             'Orders',
     //             $ordersResourceSet
     //             );
     $targetResourceSet = $targetResourceProperty->getResourceType()->getCustomState();
     if (is_null($targetResourceSet)) {
         throw new InvalidOperationException('Failed to retrieve the custom state from ' . $targetResourceProperty->getResourceType()->getName());
     }
     //Customer_Orders_Orders, Order_Customer_Customers
     $key = $sourceResourceType->getName() . '_' . $targetResourceProperty->getName() . '_' . $targetResourceSet->getName();
     if (array_key_exists($key, $this->associationSets)) {
         return $this->associationSets[$key];
     }
     return null;
 }
 public function testResourceProperty()
 {
     $addressResType = new ResourceType(new \ReflectionClass('UnitTests\\POData\\Facets\\NorthWind1\\Address2'), ResourceTypeKind::COMPLEX, 'Address', 'Northwind');
     $booleanResourcetype = ResourceType::getPrimitiveResourceType(EdmPrimitiveType::BOOLEAN);
     $isPrimaryPrimProperty = new ResourceProperty('IsPrimary', null, ResourcePropertyKind::PRIMITIVE, $booleanResourcetype);
     $addressResType->addProperty($isPrimaryPrimProperty);
     try {
         $addressComplexProperty = new ResourceProperty('Address', null, ResourcePropertyKind::COMPLEX_TYPE | ResourcePropertyKind::KEY, $addressResType);
         $this->fail('An expected InvalidArgumentException for \'invalid ResourcePropertyKind\' has not been raised');
     } catch (\InvalidArgumentException $exception) {
         $this->assertStringEndsWith('not a valid ResourcePropertyKind enum value or valid combination of ResourcePropertyKind enum values', $exception->getMessage());
     }
     $stringResourceType = ResourceType::getPrimitiveResourceType(EdmPrimitiveType::STRING);
     try {
         $addressComplexProperty = new ResourceProperty('Address', null, ResourcePropertyKind::COMPLEX_TYPE, $stringResourceType);
         $this->fail('An expected InvalidArgumentException for \'Property and ResourceType kind mismatch\' has not been raised');
     } catch (\InvalidArgumentException $exception) {
         $this->assertStringStartsWith('The \'$kind\' parameter does not match with the type of the resource type', $exception->getMessage());
     }
     $customerResType = new ResourceType(new \ReflectionClass('UnitTests\\POData\\Facets\\NorthWind1\\Customer2'), ResourceTypeKind::ENTITY, 'Customer', 'Northwind');
     $stringResourceType = ResourceType::getPrimitiveResourceType(EdmPrimitiveType::STRING);
     $customerIDPrimProperty = new ResourceProperty('CustomerID', null, ResourcePropertyKind::PRIMITIVE | ResourcePropertyKind::KEY, $stringResourceType);
     $customerNamePrimProperty = new ResourceProperty('CustomerName', null, ResourcePropertyKind::PRIMITIVE, $stringResourceType);
     $intResourceType = ResourceType::getPrimitiveResourceType(EdmPrimitiveType::INT32);
     $ratingPrimProperty = new ResourceProperty('Rating', null, ResourcePropertyKind::PRIMITIVE, $intResourceType);
     $customerResType->addProperty($customerIDPrimProperty);
     $customerResType->addProperty($customerNamePrimProperty);
     $customerResType->addProperty($ratingPrimProperty);
     $this->assertTrue($customerIDPrimProperty->isKindOf(ResourcePropertyKind::KEY));
     $this->assertTrue($customerIDPrimProperty->isKindOf(ResourcePropertyKind::PRIMITIVE));
     $customerReferenceSetProperty = new ResourceProperty('Customers', null, ResourcePropertyKind::RESOURCESET_REFERENCE, $customerResType);
     $this->assertEquals($customerReferenceSetProperty->getName(), 'Customers');
     $this->assertEquals($customerReferenceSetProperty->getKind(), ResourcePropertyKind::RESOURCESET_REFERENCE);
     $this->assertEquals($customerReferenceSetProperty->getInstanceType() instanceof \ReflectionClass, true);
     $this->assertEquals($customerReferenceSetProperty->getResourceType()->getName(), 'Customer');
     $this->assertEquals($customerReferenceSetProperty->getTypeKind(), ResourceTypeKind::ENTITY);
     $this->assertFalse($customerReferenceSetProperty->isKindOf(ResourcePropertyKind::RESOURCE_REFERENCE));
 }
 /**
  * Get the resource type of the property hold by this expression
  * 
  * @return ResourceType
  */
 public function getResourceType()
 {
     return $this->resourceProperty->getResourceType();
 }
 /**
  * To check this relationship belongs to a specific resource set, type
  * and property
  * 
  * @param ResourceSet      $resourceSet      Resource set for the association
  *                                           end
  * @param ResourceType     $resourceType     Resource type for the association
  *                                           end
  * @param ResourceProperty $resourceProperty Resource property for the 
  *                                           association end
  * 
  * @return boolean
  */
 public function isBelongsTo(ResourceSet $resourceSet, ResourceType $resourceType, ResourceProperty $resourceProperty)
 {
     return strcmp($resourceSet->getName(), $this->_resourceSet->getName()) == 0 && $this->_resourceType->isAssignableFrom($resourceType) && (is_null($resourceProperty) && is_null($this->_resourceProperty) || !is_null($resourceProperty) && !is_null($this->_resourceProperty) && strcmp($resourceProperty->getName(), $this->_resourceProperty->getName()) == 0);
 }
 /**
  * Get related resource for a resource
  * 
  * @param ResourceSet      $sourceResourceSet    The source resource set
  * @param mixed            $sourceEntityInstance The source resource
  * @param ResourceSet      $targetResourceSet    The resource set of 
  *                                               the navigation property
  * @param ResourceProperty $targetProperty       The navigation property to be 
  *                                               retrieved
  * 
  * @return object|null The related resource if exists else null
  */
 public function getRelatedResourceReference(ResourceSet $sourceResourceSet, $sourceEntityInstance, ResourceSet $targetResourceSet, ResourceProperty $targetProperty)
 {
     $result = null;
     $srcClass = get_class($sourceEntityInstance);
     $navigationPropName = $targetProperty->getName();
     switch (true) {
         case $srcClass == 'Post':
             if ($navigationPropName == 'User') {
                 $query = "SELECT * FROM `wp_users` WHERE ID = {$sourceEntityInstance->Author}";
                 $stmt = mysql_query($query);
                 $stmt = mysql_query($query);
                 $data = mysql_fetch_assoc($stmt);
                 $result = $this->_serializeUser($data);
                 if ($stmt === false) {
                     die(mysql_error());
                 }
                 if (!mysql_num_rows($stmt)) {
                     $result = null;
                 }
             } else {
                 die('Post does not have navigation porperty with name: ' . $navigationPropName);
             }
             break;
         case $srcClass == 'Comment':
             if ($navigationPropName == 'User') {
                 $query = "SELECT * FROM `wp_users` WHERE ID = {$sourceEntityInstance->UserID}";
                 $stmt = mysql_query($query);
                 if ($stmt === false) {
                     die(mysql_error());
                 }
                 if (!mysql_num_rows($stmt)) {
                     $result = null;
                 }
                 $data = mysql_fetch_assoc($stmt);
                 $result = $this->_serializeUser($data);
             } elseif ($navigationPropName == 'Post') {
                 $query = "SELECT * FROM `wp_posts` WHERE" . " wp_posts.post_type = 'post'" . " AND wp_posts.post_status = 'publish'" . " AND wp_posts.ID = {$sourceEntityInstance->PostID}";
                 $stmt = mysql_query($query);
                 if ($stmt === false) {
                     die(mysql_error());
                 }
                 if (!mysql_num_rows($stmt)) {
                     $result = null;
                 }
                 $data = mysql_fetch_assoc($stmt);
                 $result = $this->_serializePost($data);
             } else {
                 die('Comment does not have navigation porperty with name: ' . $navigationPropName);
             }
             break;
     }
     mysql_free_result($stmt);
     return $result;
 }
 /**
  * Gets the resource type on which the resource property is declared on, 
  * If property is not declared in the given resource type, then this 
  * function drill down to the inheritance hierarchy of the given resource
  * type to find out the base class in which the property is declared
  * 
  * @param ResourceType     $resourceType     The resource type to start looking
  * @param ResourceProperty $resourceProperty The resource property in question
  * 
  * @return ResourceType|null Returns reference to the ResourceType on which 
  *                                   the $resourceProperty is declared, NULL if 
  *                                   $resourceProperty is not declared anywhere 
  *                                   in the inheritance hierarchy
  */
 private function _getResourceTypeWherePropertyIsDeclared(ResourceType $resourceType, ResourceProperty $resourceProperty)
 {
     $type = $resourceType;
     while ($type !== null) {
         if ($type->resolvePropertyDeclaredOnThisType($resourceProperty->getName()) !== null) {
             break;
         }
         $type = $type->getBaseType();
     }
     return $type;
 }
 /**
  * Gets instance type of the ResourceProperty instance corresponding to 
  * this sub path segment If this sub path segment is last segment then 
  * this function returns 'IType' otherwise 'ReflectionClass'.
  * 
  * @return ReflectionClass|IType
  */
 public function getInstanceType()
 {
     return $this->_resourceProperty->getInstanceType();
 }
Exemple #15
0
 /**      
  * Add a property belongs to this resource type instance
  * 
  * @param ResourceProperty $property Property to add
  * 
  * @throws InvalidOperationException
  * @return void
  */
 public function addProperty(ResourceProperty $property)
 {
     if ($this->_resourceTypeKind == ResourceTypeKind::PRIMITIVE) {
         throw new InvalidOperationException(Messages::resourceTypeNoAddPropertyForPrimitive());
     }
     $name = $property->getName();
     foreach (array_keys($this->_propertiesDeclaredOnThisType) as $propertyName) {
         if (strcasecmp($propertyName, $name) == 0) {
             throw new InvalidOperationException(Messages::resourceTypePropertyWithSameNameAlreadyExists($propertyName, $this->_name));
         }
     }
     if ($property->isKindOf(ResourcePropertyKind::KEY)) {
         if ($this->_resourceTypeKind != ResourceTypeKind::ENTITY) {
             throw new InvalidOperationException(Messages::resourceTypeKeyPropertiesOnlyOnEntityTypes());
         }
         if ($this->_baseType != null) {
             throw new InvalidOperationException(Messages::resourceTypeNoKeysInDerivedTypes());
         }
     }
     if ($property->isKindOf(ResourcePropertyKind::ETAG) && $this->_resourceTypeKind != ResourceTypeKind::ENTITY) {
         throw new InvalidOperationException(Messages::resourceTypeETagPropertiesOnlyOnEntityTypes());
     }
     //Check for Base class properties
     $this->_propertiesDeclaredOnThisType[$name] = $property;
     // Set $this->_allProperties to null, this is very important because the
     // first call to getAllProperties will initilaize $this->_allProperties,
     // further call to getAllProperties will not reinitialize _allProperties
     // so if addProperty is called after calling getAllProperties then the
     // property just added will not be reflected in $this->_allProperties
     unset($this->_allProperties);
     $this->_allProperties = array();
 }