/**
  * Gets a related entity instance from an entity set identifed by a key
  * 
  * @param ResourceSet      $sourceResourceSet    The entity set related to
  *                                               the entity to be fetched.
  * @param object           $sourceEntityInstance The related entity instance.
  * @param ResourceSet      $targetResourceSet    The entity set from which
  *                                               entity needs to be fetched.
  * @param ResourceProperty $targetProperty       The metadata of the target 
  *                                               property.
  * @param KeyDescriptor    $keyDescriptor        The key to identify the entity 
  *                                               to be fetched.
  * 
  * @return object|null Returns entity instance if found else null
  */
 public function getResourceFromRelatedResourceSet(ResourceSet $sourceResourceSet, $sourceEntityInstance, ResourceSet $targetResourceSet, ResourceProperty $targetProperty, KeyDescriptor $keyDescriptor)
 {
     $result = array();
     $srcClass = get_class($sourceEntityInstance);
     $navigationPropName = $targetProperty->getName();
     $keys = array();
     $namedKeyValues = $keyDescriptor->getValidatedNamedValues();
     foreach ($namedKeyValues as $key => $value) {
         $keys[] = "{$key} = '{$value['0']}' ";
     }
     $conditionStr = implode(' AND ', $keys);
     switch (true) {
         case $srcClass == 'Post':
             if ($navigationPropName == 'Tags') {
                 $query = "SELECT t.*, tt.description" . " FROM wp_terms AS t" . " INNER JOIN wp_term_taxonomy AS tt" . " ON tt.term_id = t.term_id" . " INNER JOIN wp_term_relationships AS tr" . " ON tr.term_taxonomy_id = tt.term_taxonomy_id" . " WHERE tt.taxonomy IN ('post_tag')" . " AND tr.object_id IN ({$sourceEntityInstance->PostID})" . " AND tt.term_id = " . $namedKeyValues['TagID'][0];
                 $stmt = mysql_query($query);
                 $result = $this->_serializeTags($stmt);
             } elseif ($navigationPropName == 'Categories') {
                 $query = "SELECT t.*, tt.description" . " FROM wp_terms AS t" . " INNER JOIN wp_term_taxonomy AS tt" . " ON tt.term_id = t.term_id" . " INNER JOIN wp_term_relationships AS tr" . " ON tr.term_taxonomy_id = tt.term_taxonomy_id" . " WHERE tt.taxonomy IN ('category')" . " AND tr.object_id IN ({$sourceEntityInstance->PostID})" . " AND tt.term_id = " . $namedKeyValues['CategoryID'][0];
                 $stmt = mysql_query($query);
                 $result = $this->_serializeCategories($stmt);
             } else {
                 if ($navigationPropName == 'Comments') {
                     $query = "SELECT * FROM `wp_comments`" . " WHERE comment_approved = 1" . " AND comment_post_ID = {$sourceEntityInstance->PostID}" . " AND comment_ID = " . $namedKeyValues['CommentID'][0];
                     $stmt = mysql_query($query);
                     $result = $this->_serializeComments($stmt);
                 } else {
                     die('Post does not have navigation porperty with name: ' . $navigationPropName);
                 }
             }
             break;
         case $srcClass == 'Tag':
             if ($navigationPropName == 'Posts') {
                 $query = "SELECT p . *" . " FROM wp_posts AS p" . " INNER JOIN wp_term_relationships AS tr" . " ON p.ID = tr.object_id" . " INNER JOIN wp_term_taxonomy AS tt" . " ON tr.term_taxonomy_id = tt.term_taxonomy_id" . " WHERE tt.term_id = {$sourceEntityInstance->TagID}" . " AND p.post_type = 'post'" . " AND p.post_status = 'publish'" . " AND p.ID = " . $namedKeyValues['PostID'][0];
                 $stmt = mysql_query($query);
                 $result = $this->_serializePosts($stmt);
             } else {
                 die('Tag does not have navigation porperty with name: ' . $navigationPropName);
             }
             break;
         case $srcClass == 'Category':
             if ($navigationPropName == 'Posts') {
                 $query = "SELECT p . *" . " FROM wp_posts AS p" . " INNER JOIN wp_term_relationships AS tr" . " ON p.ID = tr.object_id" . " INNER JOIN wp_term_taxonomy AS tt" . " ON tr.term_taxonomy_id = tt.term_taxonomy_id" . " WHERE tt.term_id = {$sourceEntityInstance->CategoryID}" . " AND p.post_type = 'post'" . " AND p.post_status = 'publish'" . " AND p.ID = " . $namedKeyValues['PostID'][0];
                 $stmt = mysql_query($query);
                 $result = $this->_serializePosts($stmt);
             } else {
                 die('Category does not have navigation porperty with name: ' . $navigationPropName);
             }
             break;
         case $srcClass == 'Comment':
             die('Comment does not have navigation porperty with name: ' . $navigationPropName);
             break;
         case $srcClass == 'User':
             if ($navigationPropName == 'Posts') {
                 $query = "SELECT * FROM `wp_posts` WHERE" . " wp_posts.post_type = 'post'" . " AND wp_posts.post_status = 'publish'" . " AND wp_posts.post_author = {$sourceEntityInstance->UserID}" . " AND wp_posts.ID = " . $namedKeyValues['PostID'][0];
                 $stmt = mysql_query($query);
                 $result = $this->_serializePosts($stmt);
             } elseif ($navigationPropName == 'Comments') {
                 $query = "SELECT * FROM `wp_comments`" . " WHERE comment_approved = 1" . " AND wp_comments.user_id = {$sourceEntityInstance->UserID}" . " AND wp_comments.comment_ID = " . $namedKeyValues['CommentID'][0];
                 $stmt = mysql_query($query);
                 $result = $this->_serializeComments($stmt);
             } else {
                 die('User does not have navigation porperty with name: ' . $navigationPropName);
             }
             break;
     }
     mysql_free_result($stmt);
     return empty($result) ? null : $result[0];
 }
 /**
  * Gets a related entity instance from an entity set identifed by a key
  * 
  * @param ResourceSet      $sourceResourceSet    The entity set related to
  *                                               the entity to be fetched.
  * @param object           $sourceEntityInstance The related entity instance.
  * @param ResourceSet      $targetResourceSet    The entity set from which
  *                                               entity needs to be fetched.
  * @param ResourceProperty $targetProperty       The metadata of the target 
  *                                               property.
  * @param KeyDescriptor    $keyDescriptor        The key to identify the entity 
  *                                               to be fetched.
  * 
  * @return object|null Returns entity instance if found else null
  */
 public function getResourceFromRelatedResourceSet(ResourceSet $sourceResourceSet, $sourceEntityInstance, ResourceSet $targetResourceSet, ResourceProperty $targetProperty, KeyDescriptor $keyDescriptor)
 {
     $result = array();
     $srcClass = get_class($sourceEntityInstance);
     $navigationPropName = $targetProperty->getName();
     $key = null;
     foreach ($keyDescriptor->getValidatedNamedValues() as $keyName => $valueDescription) {
         $key = $key . $keyName . '=' . $valueDescription[0] . ' and ';
     }
     $key = rtrim($key, ' and ');
     if ($srcClass === 'Customer') {
         if ($navigationPropName === 'Orders') {
             $query = "SELECT * FROM Orders WHERE CustomerID = '{$sourceEntityInstance->CustomerID}' and {$key}";
             $stmt = sqlsrv_query($this->_connectionHandle, $query);
             if ($stmt === false) {
                 $errorAsString = self::_getSQLSRVError();
                 throw ODataException::createInternalServerError($errorAsString);
             }
             $result = $this->_serializeOrders($stmt);
         } else {
             die('Customer does not have navigation porperty with name: ' . $navigationPropName);
         }
     } else {
         if ($srcClass === 'Order') {
             if ($navigationPropName === 'Order_Details') {
                 $query = "SELECT * FROM [Order Details] WHERE OrderID = {$sourceEntityInstance->OrderID}";
                 $stmt = sqlsrv_query($this->_connectionHandle, $query);
                 if ($stmt === false) {
                     $errorAsString = self::_getSQLSRVError();
                     throw ODataException::createInternalServerError($errorAsString);
                 }
                 $result = $this->_serializeOrderDetails($stmt);
             } else {
                 die('Order does not have navigation porperty with name: ' . $navigationPropName);
             }
         }
     }
     return empty($result) ? null : $result[0];
 }
 /**
  * Validate the given entity instance.
  * 
  * @param object        $entityInstance Entity instance to validate
  * @param ResourceSet   &$resourceSet   Resource set to which the entity 
  *                                      instance belongs to.
  * @param KeyDescriptor &$keyDescriptor The key descriptor.
  * @param string        $methodName     Method from which this function 
  *                                      invoked.
  *
  * @return void
  * 
  * @throws ODataException
  */
 private function _validateEntityInstance($entityInstance, ResourceSet &$resourceSet, KeyDescriptor &$keyDescriptor, $methodName)
 {
     if (is_null($entityInstance)) {
         throw ODataException::createResourceNotFoundError($resourceSet->getName());
     }
     // lion:
     if ($_SERVER['REQUEST_METHOD'] == HTTPRequestMethod::DELETE()) {
         return;
     }
     $entityName = $resourceSet->getResourceType()->getInstanceType()->getName();
     if (!is_object($entityInstance) || !$entityInstance instanceof $entityName) {
         throw ODataException::createInternalServerError(Messages::providersWrapperIDSQPMethodReturnsUnExpectedType($entityName, $methodName));
     }
     foreach ($keyDescriptor->getValidatedNamedValues() as $keyName => $valueDescription) {
         try {
             $keyProperty = new \ReflectionProperty($entityInstance, $keyName);
             $keyValue = $keyProperty->getValue($entityInstance);
             if (is_null($keyValue)) {
                 throw ODataException::createInternalServerError(Messages::providersWrapperIDSQPMethodReturnsInstanceWithNullKeyProperties($methodName));
             }
             $convertedValue = $valueDescription[1]->convert($valueDescription[0]);
             if ($keyValue != $convertedValue) {
                 throw ODataException::createInternalServerError(Messages::providersWrapperIDSQPMethodReturnsInstanceWithNonMatchingKeys($methodName));
             }
         } catch (\ReflectionException $reflectionException) {
             //throw ODataException::createInternalServerError(
             //  Messages::orderByParserFailedToAccessOrInitializeProperty(
             //      $resourceProperty->getName(), $resourceType->getName()
             //  )
             //);
         }
     }
 }