saintsystems / odata-client-php

OData Client Library for PHP
MIT License
141 stars 103 forks source link

ODataResponse return type and collect #129

Closed Involture closed 1 year ago

Involture commented 1 year ago

How to reproduce

  1. Create a new client and set entityReturnType to retreive raw ODataResponse objects from queries :
    $client = new ODataClient($baseUrl);
    $client->setEntityReturnType(false);
  2. Call a method thats supposed to return a single object :
    $result = $client->from('People')->find('Elvis');
  3. Get the originating request as a result. print_r($result) :
    \SaintSystems\OData\ODataRequest { ... }

Cause

Here is the data flow and the associated return value types (read return types from bottom up)

  1. Query\Builder::find
    return $this->whereKey($id)->first($properties);
    • whereKey returns a Builder
    • first returns an ODataRequest
  2. Query\Builder::first
    return $this->take(1)->get($properties)->first();
    • Query\Builder::get returns an Illuminate/Collection containing an ODataRequest in first position.
    • Illuminate\Collection::first returns the first element of the collection
  3. Query\Builder::get
    $results = $this->processor->processSelect($this, $this->runGet());
    return collect($results);
    • Query\Builder::runGet returns a ODataReponse
    • Processor::processSelect is the identitfy function and returns the same ODataResponse
    • Illuminate\collect takes the ODataResponse and insert its field in a new collection. The first field of an ODataResponse is the associated request.
  4. Query\Builder::runGet : returns an ODataResponse
  5. ODataClient::get : returns an ODataResponse
  6. ODataClient::request : returns an ODataResponse
  7. ODataRequest::execute
    
    $returnObj = $response;

$returnType = is_null($this->returnType) ? Entity::class : $this->returnType;

if ($returnType) { $returnObj = $response->getResponseAsObject($returnType); } return $returnObj;


If the `returnType` is anything but false, `ODataResponse::getResponseAsObject` and returns an **array** of object. This array then gets correctly mapped to a collection.

The problem is that everything assumes that `ODataRequest::execute` returns an array of object, but that is not the case when `returnType` is false

### Proposed solution
Wrap the raw response in an array when `returnType` is false
PR incoming