src/POData/BaseService.php
/**
     * Serialize the requested resource.
     * 
     * @param RequestDescription $request The description of the request  submitted by the client.
     * @param UriProcessor $uriProcessor Reference to the uri processor.
     * 
     * @return void
     */
Serialize the requested resource.

@param RequestDescription $request The description of the request  submitted by the client.
@param UriProcessor $uriProcessor Reference to the uri processor.

@return void
Serialize the requested resource . @param RequestDescription $request The description of the request submitted by the client . @param UriProcessor $uriProcessor Reference to the uri processor . @return void
protected function serializeResult(RequestDescription $request, UriProcessor $uriProcessor) {
        $isETagHeaderAllowed = $request->isETagHeaderAllowed();
        if ($this->config->getValidateETagHeader() && !$isETagHeaderAllowed) {
            if (!is_null($this->_serviceHost->getRequestIfMatch())
                ||!is_null($this->_serviceHost->getRequestIfNoneMatch())
            ) {
                throw ODataException::createBadRequestError(
                    Messages::eTagCannotBeSpecified($this->getHost()->getAbsoluteRequestUri()->getUrlAsString())
                );
            }
        }
        $responseContentType = self::getResponseContentType($request, $uriProcessor, $this);
	    if (is_null($responseContentType) && $request->getTargetKind() != TargetKind::MEDIA_RESOURCE()) {
		    throw new ODataException( Messages::unsupportedMediaType(), 415 );
	    }
	    $odataModelInstance = null;
        $hasResponseBody = true;
         (1) media resource - For Media resource 'getResponseContentType' already performed execution as it needs to know the mime type of the stream
         (2) metadata - internal resource
         (3) service directory - internal resource
        if ($request->needExecution()) {
            $uriProcessor->execute();
            $objectModelSerializer = new ObjectModelSerializer($this, $request);
            if (!$request->isSingleResult()) {
                 Code path for collection (feed or links)
                $entryObjects = $request->getTargetResult();
                self::assert(
                    !is_null($entryObjects) && is_array($entryObjects), 
                    '!is_null($entryObjects) && is_array($entryObjects)'
                );
                 If related resource set is empty for an entry then we should 
                 not throw error instead response must be empty feed or empty links
                if ($request->isLinkUri()) {
                    $odataModelInstance = $objectModelSerializer->writeUrlElements($entryObjects);
                    self::assert(
                        $odataModelInstance instanceof \POData\ObjectModel\ODataURLCollection, 
                        '$odataModelInstance instanceof ODataURLCollection'
                    );
                } else {
                    $odataModelInstance = $objectModelSerializer->writeTopLevelElements($entryObjects);
                    self::assert(
                        $odataModelInstance instanceof \POData\ObjectModel\ODataFeed, 
                        '$odataModelInstance instanceof ODataFeed'
                    );
                }
            } else {
                 Code path for entry, complex, bag, resource reference link, 
                 primitive type or primitive value
                $result = $request->getTargetResult();
                $requestTargetKind = $request->getTargetKind();
                if ($request->isLinkUri()) {
                     In the query 'Orders(1245)/$links/Customer', the targeted
                     Customer might be null
                    if (is_null($result)) {
						throw ODataException::createResourceNotFoundError(
                            $request->getIdentifier()
                        );
                    }
                    $odataModelInstance = $objectModelSerializer->writeUrlElement($result);
                } else if ($requestTargetKind == TargetKind::RESOURCE()) {
                    if (!is_null($this->_serviceHost->getRequestIfMatch())
                        && !is_null($this->_serviceHost->getRequestIfNoneMatch())
                    ) {
						throw ODataException::createBadRequestError(
                            Messages::bothIfMatchAndIfNoneMatchHeaderSpecified()
                        );
                    }
                     handle entry resource
                    $needToSerializeResponse = true;
                    $targetResourceType = $request->getTargetResourceType();
                    $eTag = $this->compareETag(
                        $result, 
                        $targetResourceType, 
                        $needToSerializeResponse
                    );
                    if ($needToSerializeResponse) {
                        if (is_null($result)) {
                             In the query 'Orders(1245)/Customer', the targeted
                             Customer might be null
                             set status code to 204 => 'No Content'
                            $this->_serviceHost->setResponseStatusCode(HttpStatus::CODE_NOCONTENT);
                            $hasResponseBody = false;
                        } else {
                            $odataModelInstance = $objectModelSerializer->writeTopLevelElement($result);
                        }
                    } else {
                         Resource is not modified so set status code 
                         to 304 => 'Not Modified'
                        $this->_serviceHost->setResponseStatusCode(HttpStatus::CODE_NOT_MODIFIED);
                        $hasResponseBody = false;
                    }
                     if resource has eTagProperty then eTag header needs to written
                    if (!is_null($eTag)) {
                        $this->_serviceHost->setResponseETag($eTag);
                    }
                } else if ($requestTargetKind == TargetKind::COMPLEX_OBJECT()) {
	                $odataModelInstance = $objectModelSerializer->writeTopLevelComplexObject(
                        $result, 
                        $request->getProjectedProperty()->getName(),
	                    $request->getTargetResourceType()
	                );
                } else if ($requestTargetKind == TargetKind::BAG()) {
                    $odataModelInstance = $objectModelSerializer->writeTopLevelBagObject(
                        $result, 
                        $request->getProjectedProperty()->getName(),
	                    $request->getTargetResourceType(),
                        $odataModelInstance
                    );
                } else if ($requestTargetKind == TargetKind::PRIMITIVE()) {
                    $odataModelInstance = $objectModelSerializer->writeTopLevelPrimitive(
                        $result,
	                    $request->getProjectedProperty(),
                        $odataModelInstance
                    );
                } else if ($requestTargetKind == TargetKind::PRIMITIVE_VALUE()) {
                     Code path for primitive value (Since its primitve no need for
                     object model serialization) 
                     Customers('ANU')/CompanyName/$value => string 
                     Employees(1)/Photo/$value => binary stream
                     Customers/$count => string
                } else {
                    self::assert(false, 'Unexpected resource target kind');
                }
            }
        }
        Note: Response content type can be null for named stream
        if ($hasResponseBody && !is_null($responseContentType)) {
            if ($request->getTargetKind() != TargetKind::MEDIA_RESOURCE() && $responseContentType != MimeTypes::MIME_APPLICATION_OCTETSTREAM) {
	            append charset for everything except:
	            stream resources as they have their own content type
	            binary properties (they content type will be App Octet for those...is this a good way? we could also decide based upon the projected property
                $responseContentType .= ';charset=utf-8';
            }
        }
        if ($hasResponseBody) {
            ResponseWriter::write(
                $this, 
                $request,
                $odataModelInstance, 
                $responseContentType
            );
        }
    }
protected function serializeResult ( RequestDescription $ request , UriProcessor $ uriProcessor ) { $ isETagHeaderAllowed = $ request -> isETagHeaderAllowed ( ) ; if ( $ this -> config -> getValidateETagHeader ( ) && ! $ isETagHeaderAllowed ) { if ( ! is_null ( $ this -> _serviceHost -> getRequestIfMatch ( ) ) || ! is_null ( $ this -> _serviceHost -> getRequestIfNoneMatch ( ) ) ) { throw ODataException :: createBadRequestError ( Messages :: eTagCannotBeSpecified ( $ this -> getHost ( ) -> getAbsoluteRequestUri ( ) -> getUrlAsString ( ) ) ) ; } } $ responseContentType = self :: getResponseContentType ( $ request , $ uriProcessor , $ this ) ; if ( is_null ( $ responseContentType ) && $ request -> getTargetKind ( ) != TargetKind :: MEDIA_RESOURCE ( ) ) { throw new ODataException ( Messages :: unsupportedMediaType ( ) , 415 ) ; } $ odataModelInstance = null ; $ hasResponseBody = true ; if ( $ request -> needExecution ( ) ) { $ uriProcessor -> execute ( ) ; $ objectModelSerializer = new ObjectModelSerializer ( $ this , $ request ) ; if ( ! $ request -> isSingleResult ( ) ) { $ entryObjects = $ request -> getTargetResult ( ) ; self :: assert ( ! is_null ( $ entryObjects ) && is_array ( $ entryObjects ) , '!is_null($entryObjects) && is_array($entryObjects)' ) ; if ( $ request -> isLinkUri ( ) ) { $ odataModelInstance = $ objectModelSerializer -> writeUrlElements ( $ entryObjects ) ; self :: assert ( $ odataModelInstance instanceof \ POData \ ObjectModel \ ODataURLCollection , '$odataModelInstance instanceof ODataURLCollection' ) ; } else { $ odataModelInstance = $ objectModelSerializer -> writeTopLevelElements ( $ entryObjects ) ; self :: assert ( $ odataModelInstance instanceof \ POData \ ObjectModel \ ODataFeed , '$odataModelInstance instanceof ODataFeed' ) ; } } else { $ result = $ request -> getTargetResult ( ) ; $ requestTargetKind = $ request -> getTargetKind ( ) ; if ( $ request -> isLinkUri ( ) ) { if ( is_null ( $ result ) ) { throw ODataException :: createResourceNotFoundError ( $ request -> getIdentifier ( ) ) ; } $ odataModelInstance = $ objectModelSerializer -> writeUrlElement ( $ result ) ; } else if ( $ requestTargetKind == TargetKind :: RESOURCE ( ) ) { if ( ! is_null ( $ this -> _serviceHost -> getRequestIfMatch ( ) ) && ! is_null ( $ this -> _serviceHost -> getRequestIfNoneMatch ( ) ) ) { throw ODataException :: createBadRequestError ( Messages :: bothIfMatchAndIfNoneMatchHeaderSpecified ( ) ) ; } $ needToSerializeResponse = true ; $ targetResourceType = $ request -> getTargetResourceType ( ) ; $ eTag = $ this -> compareETag ( $ result , $ targetResourceType , $ needToSerializeResponse ) ; if ( $ needToSerializeResponse ) { if ( is_null ( $ result ) ) { $ this -> _serviceHost -> setResponseStatusCode ( HttpStatus :: CODE_NOCONTENT ) ; $ hasResponseBody = false ; } else { $ odataModelInstance = $ objectModelSerializer -> writeTopLevelElement ( $ result ) ; } } else { $ this -> _serviceHost -> setResponseStatusCode ( HttpStatus :: CODE_NOT_MODIFIED ) ; $ hasResponseBody = false ; } if ( ! is_null ( $ eTag ) ) { $ this -> _serviceHost -> setResponseETag ( $ eTag ) ; } } else if ( $ requestTargetKind == TargetKind :: COMPLEX_OBJECT ( ) ) { $ odataModelInstance = $ objectModelSerializer -> writeTopLevelComplexObject ( $ result , $ request -> getProjectedProperty ( ) -> getName ( ) , $ request -> getTargetResourceType ( ) ) ; } else if ( $ requestTargetKind == TargetKind :: BAG ( ) ) { $ odataModelInstance = $ objectModelSerializer -> writeTopLevelBagObject ( $ result , $ request -> getProjectedProperty ( ) -> getName ( ) , $ request -> getTargetResourceType ( ) , $ odataModelInstance ) ; } else if ( $ requestTargetKind == TargetKind :: PRIMITIVE ( ) ) { $ odataModelInstance = $ objectModelSerializer -> writeTopLevelPrimitive ( $ result , $ request -> getProjectedProperty ( ) , $ odataModelInstance ) ; } else if ( $ requestTargetKind == TargetKind :: PRIMITIVE_VALUE ( ) ) { } else { self :: assert ( false , 'Unexpected resource target kind' ) ; } } } if ( $ hasResponseBody && ! is_null ( $ responseContentType ) ) { if ( $ request -> getTargetKind ( ) != TargetKind :: MEDIA_RESOURCE ( ) && $ responseContentType != MimeTypes :: MIME_APPLICATION_OCTETSTREAM ) { $ responseContentType .= ';charset=utf-8' ; } } if ( $ hasResponseBody ) { ResponseWriter :: write ( $ this , $ request , $ odataModelInstance , $ responseContentType ) ; } }
Serialize the requested resource.
Serialize the requested resource .
//the responseContentType can ONLY be null if it's a stream (media resource) and that stream is storing null as the content type // Execution required at this point if request target to any resource other than // // (1) media resource - For Media resource 'getResponseContentType' already performed execution as it needs to know the mime type of the stream // (2) metadata - internal resource // (3) service directory - internal resource // Code path for collection (feed or links) // If related resource set is empty for an entry then we should  // not throw error instead response must be empty feed or empty links // Code path for entry, complex, bag, resource reference link,  // primitive type or primitive value // In the query 'Orders(1245)/$links/Customer', the targeted // Customer might be null // handle entry resource // In the query 'Orders(1245)/Customer', the targeted // Customer might be null // set status code to 204 => 'No Content' // Resource is not modified so set status code  // to 304 => 'Not Modified' // if resource has eTagProperty then eTag header needs to written // Code path for primitive value (Since its primitve no need for // object model serialization)  // Customers('ANU')/CompanyName/$value => string  // Employees(1)/Photo/$value => binary stream // Customers/$count => string //Note: Response content type can be null for named stream //append charset for everything except: //stream resources as they have their own content type //binary properties (they content type will be App Octet for those...is this a good way? we could also decide based upon the projected property //