config = $config; $this->preferences = $preferences; $this->metadata = $metadata; } public function process(Params $params, Data $data): StreamInterface { $attributeList = $params->getAttributeList(); $delimiterRaw = $this->preferences->get('exportDelimiter') ?? $this->config->get('exportDelimiter') ?? ','; $delimiter = str_replace('\t', "\t", $delimiterRaw); $fp = fopen('php://temp', 'w'); if ($fp === false) { throw new RuntimeException("Could not open temp."); } fputcsv($fp, $attributeList, $delimiter); while (($row = $data->readRow()) !== null) { $preparedRow = $this->prepareRow($row); fputcsv($fp, $preparedRow, $delimiter, '"' , "\0"); } rewind($fp); return new Stream($fp); } /** * @param mixed[] $row * @return mixed[] */ protected function prepareRow(array $row): array { $preparedRow = []; foreach ($row as $item) { if (is_array($item) || is_object($item)) { $item = Json::encode($item); } $preparedRow[] = $this->sanitizeCell($item); } return $preparedRow; } /** * @param string[] $fieldList */ public function loadAdditionalFields(Entity $entity, array $fieldList): void { if (!$entity instanceof CoreEntity) { return; } foreach ($fieldList as $field) { $fieldType = $this->metadata ->get(['entityDefs', $entity->getEntityType(), 'fields', $field, 'type']); if ( $fieldType === 'linkMultiple' || $fieldType === 'attachmentMultiple' ) { if (!$entity->has($field . 'Ids')) { $entity->loadLinkMultipleField($field); } } } } /** * @param mixed $value * @return mixed */ private function sanitizeCell($value) { if (!is_string($value)) { return $value; } if ($value === '') { return $value; } if (in_array($value[0], ['+', '-', '@', '='])) { return "'" . $value; } return $value; } }