/** * @test */ public function convertObjectToArrayConvertsNestedObjectsToArray() { $object = new \stdClass(); $object->a = 'v'; $object->b = new \stdClass(); $object->b->c = 'w'; $object->d = array('i' => 'foo', 'j' => 12, 'k' => TRUE, 'l' => new \stdClass()); $array = \TYPO3\Flow\Utility\Arrays::convertObjectToArray($object); $expected = array('a' => 'v', 'b' => array('c' => 'w'), 'd' => array('i' => 'foo', 'j' => 12, 'k' => TRUE, 'l' => array())); $this->assertEquals($expected, $array); }
/** * Converts the given request body according to the specified media type * Override this method in your custom TypeConverter to support additional media types * * @param string $requestBody the raw request body * @param string $mediaType the configured media type (for example "application/json") * @return array * @api */ protected function convertMediaType($requestBody, $mediaType) { $mediaTypeParts = MediaTypes::parseMediaType($mediaType); if (!isset($mediaTypeParts['subtype']) || $mediaTypeParts['subtype'] === '') { return []; } $result = []; switch ($mediaTypeParts['subtype']) { case 'json': case 'x-json': case 'javascript': case 'x-javascript': $result = json_decode($requestBody, true); if ($result === null) { return []; } break; case 'xml': $entityLoaderValue = libxml_disable_entity_loader(true); try { $xmlElement = new \SimpleXMLElement(urldecode($requestBody), LIBXML_NOERROR); libxml_disable_entity_loader($entityLoaderValue); } catch (\Exception $exception) { libxml_disable_entity_loader($entityLoaderValue); return []; } $result = Arrays::convertObjectToArray($xmlElement); break; case 'x-www-form-urlencoded': default: parse_str($requestBody, $result); break; } return $result; }
/** * Converts the given request body according to the specified media type * Override this method in your custom TypeConverter to support additional media types * * @param string $requestBody the raw request body * @param string $mediaType the configured media type (for example "application/json") * @return array * @api */ protected function convertMediaType($requestBody, $mediaType) { $mediaTypeParts = MediaTypes::parseMediaType($mediaType); if (!isset($mediaTypeParts['subtype']) || $mediaTypeParts['subtype'] === '') { return array(); } $result = array(); switch ($mediaTypeParts['subtype']) { case 'json': case 'x-json': case 'javascript': case 'x-javascript': $result = json_decode($requestBody, TRUE); if ($result === NULL) { return array(); } break; case 'xml': try { $xmlElement = new \SimpleXMLElement(urldecode($requestBody), LIBXML_NOERROR); } catch (\Exception $e) { return array(); } $result = Arrays::convertObjectToArray($xmlElement); break; case 'x-www-form-urlencoded': default: parse_str($requestBody, $result); break; } return $result; }
/** * Process CouchDB results, add metadata and process object * values by loading objects. This method processes documents * batched for loading nested entities. * * @param array $documents Documents as objects * @param array &$knownObjects * @return array * @author Christopher Hlubek <*****@*****.**> */ protected function documentsToObjectData(array $documents, array &$knownObjects = array()) { $identifiersToFetch = array(); $data = array(); foreach ($documents as $document) { $objectData = \TYPO3\Flow\Utility\Arrays::convertObjectToArray($document); // CouchDB marks documents as deleted, we need to skip these documents here if (isset($objectData['deleted']) && $objectData['deleted'] === TRUE) { continue; } $objectData['identifier'] = $objectData['_id']; $objectData['metadata'] = array('CouchDB_Revision' => $objectData['_rev']); unset($objectData['_id']); unset($objectData['_rev']); $knownObjects[$objectData['identifier']] = TRUE; if (!isset($objectData['classname'])) { throw new \TYPO3\CouchDB\InvalidResultException('Expected property "classname" in document', 1290442039, NULL, $document); } if (!$this->reflectionService->isClassReflected($objectData['classname'])) { throw new \TYPO3\CouchDB\InvalidResultException('Class "' . $objectData['classname'] . '" was not registered', 1290442092, NULL, $document); } $this->processResultProperties($objectData['properties'], $identifiersToFetch, $knownObjects, $this->reflectionService->getClassSchema($objectData['classname'])); $data[] = $objectData; } if (count($identifiersToFetch) > 0) { $documents = $this->resultToDocuments($this->doOperation(function (Client $client) use($identifiersToFetch) { return $client->getDocuments(array_keys($identifiersToFetch), array('include_docs' => TRUE)); })); $fetchedObjectsData = $this->documentsToObjectData($documents, $knownObjects); foreach ($fetchedObjectsData as $fetchedObjectData) { $identifiersToFetch[$fetchedObjectData['identifier']] = $fetchedObjectData; } } return $data; }
/** * Decodes the given request body, depending on the given content type. * * Currently JSON, XML and encoded forms are supported. The media types accepted * for choosing the respective decoding algorithm are rather broad. This method * does, for example, accept "text/x-json" although "application/json" is the * only valid (that is, IANA registered) media type for JSON. * * In future versions of Flow, this part maybe extensible by third-party code. * For the time being, only the mentioned media types are supported. * * Errors are silently ignored and result in an empty array. * * @param string $body The request body * @param string $mediaType The IANA Media Type * @return array The decoded body */ protected function decodeBodyArguments($body, $mediaType) { switch (MediaTypes::trimMediaType($mediaType)) { case 'application/json': case 'application/x-javascript': case 'text/javascript': case 'text/x-javascript': case 'text/x-json': $arguments = json_decode($body, TRUE); if ($arguments === NULL) { return array(); } break; case 'text/xml': case 'application/xml': try { $xmlElement = new \SimpleXMLElement(urldecode($body), LIBXML_NOERROR); } catch (\Exception $e) { return array(); } $arguments = Arrays::convertObjectToArray($xmlElement); break; case 'application/x-www-form-urlencoded': default: parse_str($body, $arguments); break; } return $arguments; }