/** * * * IMPORTANT: The representation of the data will be placed back into the original location/position in the $record * from which it was "normalized". This means that any client-side handlers will have to deal with the bogus * determinations. Just be aware. * * Below is a side-by-side comparison of record data as shown sent by or returned to the caller, and sent to an * event handler. * * REST API v1.0 Event Representation * ------------- -------------------- * Single row... Add a 'record' key and make it look like a multi-row * * array( array( * 'id' => 1, 'record' => array( * ) 0 => array( 'id' => 1, ), * ), * ), * * Multi-row... Stays the same...or gets wrapped by adding a 'record' key * * array( array( * 'record' => array( 'record' => array( * 0 => array( 'id' => 1 ), 0 => array( 'id' => 1 ), * 1 => array( 'id' => 2 ), 1 => array( 'id' => 2 ), * 2 => array( 'id' => 3 ), 2 => array( 'id' => 3 ), * ), ), * ) ) * * or... * * array( array( * 0 => array( 'id' => 1 ), 'record' => array( * 1 => array( 'id' => 2 ), 0 => array( 'id' => 1 ), * 2 => array( 'id' => 3 ), 1 => array( 'id' => 2 ), * ), 2 => array( 'id' => 3 ), * ), * ) */ protected function detectRequestMembers() { $wrapper = ResourcesWrapper::getWrapper(); // override - don't call parent class here $this->payload = $this->getPayloadData(); if (!empty($this->resource)) { if (!empty($this->resourceId)) { if (!empty($this->payload)) { // fix wrapper on posted single record if (!isset($this->payload[$wrapper])) { // single records don't use the record wrapper, so wrap it $this->payload = [$wrapper => [$this->payload]]; } } } elseif (ArrayUtils::isArrayNumeric($this->payload)) { // import from csv, etc doesn't include a wrapper, so wrap it $this->payload = [$wrapper => $this->payload]; } else { if (!empty($this->payload)) { switch ($this->request->getMethod()) { case Verbs::POST: case Verbs::PUT: case Verbs::PATCH: case Verbs::MERGE: // fix wrapper on posted single record if (!isset($this->payload[$wrapper])) { // stuff it back in for event $this->payload[$wrapper] = [$this->payload]; } break; } } } $this->options = $this->request->getParameters(); // merge in possible payload options $optionNames = [ApiOptions::LIMIT, ApiOptions::OFFSET, ApiOptions::ORDER, ApiOptions::GROUP, ApiOptions::FIELDS, ApiOptions::IDS, ApiOptions::FILTER, ApiOptions::PARAMS, ApiOptions::CONTINUES, ApiOptions::ROLLBACK]; foreach ($optionNames as $key => $value) { if (!array_key_exists($value, $this->options)) { if (array_key_exists($value, $this->payload)) { $this->options[$value] = $this->payload[$value]; } elseif (!empty($otherNames = ApiOptions::getAliases($value))) { foreach ($otherNames as $other) { if (!array_key_exists($other, $this->options)) { if (array_key_exists($other, $this->payload)) { $this->options[$value] = $this->payload[$other]; } } else { $this->options[$value] = $this->options[$other]; } } } } } // set defaults if not present if (Verbs::GET == $this->request->getMethod()) { // default for GET should be "return all fields" if (!array_key_exists(ApiOptions::FIELDS, $this->options)) { $this->options[ApiOptions::FIELDS] = '*'; } } // Add server side filtering properties $resource = $this->name . '/' . $this->resource; if (null != ($ssFilters = Session::getServiceFilters($this->getRequestedAction(), $this->parent->name, $resource))) { $this->options['ss_filters'] = $ssFilters; } } }