/**
  * {@inheritDoc}
  */
 protected function _executeReadQuery(Query $query, array $options = [])
 {
     $parameters = $query->where();
     if ($query->clause('limit')) {
         $parameters['count'] = $query->clause('limit');
     }
     if ($query->clause('page')) {
         $parameters['page'] = $query->clause('page');
     }
     if ($query->clause('offset')) {
         $parameters['since_id'] = $query->clause('offset');
     }
     if (!empty($query->where())) {
         $displayField = $query->endpoint()->aliasField($query->endpoint()->displayField());
         if (isset($query->where()[$displayField])) {
             $parameters['q'] = $query->where()[$displayField];
         }
     }
     $index = $this->_defaultIndex();
     if (isset($query->getOptions()['index'])) {
         $index = $query->getOptions()['index'];
     }
     $url = $this->_baseUrl() . '/' . $index . '.json';
     if ($this->nestedResource($query->clause('where'))) {
         $url = $this->nestedResource($query->clause('where'));
     }
     if (isset($query->where()['id']) && is_array($query->where()['id'])) {
         $parameters[$query->endpoint()->primaryKey()] = implode(',', $query->where()['id']);
         $url = $this->_baseUrl() . '/lookup.json';
     }
     try {
         $json = $this->_doRequest($url, $parameters);
     } catch (NotFoundException $exception) {
         return new ResultSet([], 0);
     }
     if ($json === false) {
         return false;
     }
     if (key($json) !== 0) {
         $resource = $this->_transformResource($query->endpoint(), $json);
         return new ResultSet([$resource], 1);
     }
     $resources = $this->_transformResults($query->endpoint(), $json);
     return new ResultSet($resources, count($resources));
 }
 /**
  * {@inheritDoc}
  */
 protected function _executeReadQuery(Query $query, array $options = [])
 {
     $url = $this->getBaseUrl();
     $requestParameters = [];
     $requestOptions = [];
     // Set API key if necessary
     if ($this->driver()->config('api_key')) {
         $requestParameters['key'] = $this->driver()->config('api_key');
     }
     // Single resource
     if (isset($query->clause('where')['id']) && !is_array($query->clause('where')['id'])) {
         $url .= '/' . $query->clause('where')['id'];
     } else {
         // Loop over conditions and apply them to the query
         foreach ($query->clause('where') as $field => $value) {
             $column = $query->endpoint()->schema()->column($field);
             // Custom fields should use cf_x as parameter
             if ($column['custom_field_id']) {
                 $field = 'cf_' . $column['custom_field_id'];
             }
             $requestParameters[$field] = $value;
         }
     }
     $url .= '.json';
     $orderClauses = [];
     // Turn ORM order clauses in a query parameter
     foreach ($query->clause('order') as $field => $value) {
         if (is_int($field)) {
             $field = $value;
         }
         if (!in_array($value, ['ASC', 'DESC'])) {
             $value = null;
         }
         if (!$value) {
             $orderClauses[] = $field;
             continue;
         }
         // Replace ASC with asc and DESC with desc
         $orderClauses[] = $field . ':' . str_replace(['ASC', 'DESC'], ['asc', 'desc'], $value);
     }
     if (!empty($orderClauses)) {
         $requestParameters['sort'] = implode($orderClauses, ',');
     }
     if ($query->clause('limit')) {
         $requestParameters['limit'] = $query->clause('limit');
     }
     if ($query->clause('offset')) {
         $requestParameters['offset'] = $query->clause('offset');
     }
     // Include details using the API
     if (isset($query->getOptions()['include'])) {
         $include = $query->getOptions()['include'];
         // If the value isn't a array, for example a string put it in a string
         if (!is_array($include)) {
             $include = [$include];
         }
         $requestParameters['include'] = implode(',', $include);
     }
     // Switch user if the 'user' options has been given
     if (isset($query->getOptions()['user'])) {
         $requestOptions['headers']['X-Redmine-Switch-User'] = $query->getOptions()['user'];
     }
     /* @var \Cake\Network\Http\Response $response */
     $response = $this->driver()->client()->get($url, $requestParameters, $requestOptions);
     if (!$response->isOk()) {
         throw new UnexpectedStatusCodeException([$response->statusCode()]);
     }
     // Single resource
     if (isset($query->clause('where')['id'])) {
         // Turn result into resources
         $resource = $this->_transformResource($response->json[Inflector::singularize($this->endpoint())], $query->endpoint());
         return new ResultSet([$resource], 1);
     }
     if (!isset($response->json[$this->endpoint()])) {
         throw new MissingResultsException([$url]);
     }
     $results = $response->json[$this->endpoint()];
     $total = count($results);
     // Set the amount if results to total_count if it has been provided by the API
     if (isset($response->json['total_count'])) {
         $total = $response->json['total_count'];
     }
     // Turn results into resources
     $resources = $this->_transformResults($results, $query->endpoint());
     return new ResultSet($resources, $total);
 }