Skip to content

Commit cbfd773

Browse files
Merge pull request #119 from TheDragonCode/1.x
Added `CSV` feeds format
2 parents 9bbcf95 + e0545a6 commit cbfd773

29 files changed

+362
-7
lines changed

config/feeds.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,5 +114,15 @@
114114
*/
115115
'options' => JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE,
116116
],
117+
118+
'csv' => [
119+
/**
120+
* CSV specific options applied when exporting feeds in CSV format.
121+
*/
122+
/**
123+
* The delimiter used to separate values. Common values are "," or ";".
124+
*/
125+
'delimiter' => ';',
126+
],
117127
],
118128
];

docs/labels.list

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,8 @@
1515
Available for JSON Lines feeds
1616
</secondary-label>
1717

18+
<secondary-label id="format-csv" name="csv" color="blue">
19+
Available for CSV feeds
20+
</secondary-label>
21+
1822
</labels>

docs/topics/elements.topic

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
<secondary-label ref="format-xml" />
4949
<secondary-label ref="format-json" />
5050
<secondary-label ref="format-jsonl" />
51+
<secondary-label ref="format-csv" />
5152

5253
<p>
5354
To add information to the beginning of the root element (if present) or without it,

docs/topics/supported-formats.topic

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
<def title="jsonl">
2323
Generates feeds in JSON Lines format.
2424
</def>
25+
<def title="csv">
26+
Generates feeds in CSV format.
27+
</def>
2528
</deflist>
2629

2730
<p>

src/Converters/CsvConverter.php

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace DragonCode\LaravelFeed\Converters;
6+
7+
use DragonCode\LaravelFeed\Feeds\Feed;
8+
use DragonCode\LaravelFeed\Feeds\Items\FeedItem;
9+
use DragonCode\LaravelFeed\Services\TransformerService;
10+
use Illuminate\Container\Attributes\Config;
11+
12+
use function implode;
13+
use function is_array;
14+
15+
class CsvConverter extends Converter
16+
{
17+
public function __construct(
18+
#[Config('feeds.converters.csv.delimiter')]
19+
protected string $delimiter,
20+
TransformerService $transformer
21+
) {
22+
parent::__construct(false, $transformer);
23+
}
24+
25+
public function header(Feed $feed): string
26+
{
27+
return '';
28+
}
29+
30+
public function footer(Feed $feed): string
31+
{
32+
return '';
33+
}
34+
35+
public function root(Feed $feed): string
36+
{
37+
return '';
38+
}
39+
40+
public function item(FeedItem $item, bool $isLast): string
41+
{
42+
$data = $this->performItem($item->toArray());
43+
44+
return $this->toCsv($data);
45+
}
46+
47+
public function info(array $info, bool $afterRoot): string
48+
{
49+
$data = $this->performItem($info);
50+
51+
return $this->toCsv($data);
52+
}
53+
54+
protected function performItem(array $data): array
55+
{
56+
foreach ($data as &$value) {
57+
if (is_array($value)) {
58+
$value = $this->performItem($value);
59+
60+
continue;
61+
}
62+
63+
$value = $this->transformValue($value);
64+
}
65+
66+
return $data;
67+
}
68+
69+
protected function toCsv(array $data): string
70+
{
71+
return implode($this->delimiter, $data);
72+
}
73+
}

src/Converters/JsonLinesConverter.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,9 @@ class JsonLinesConverter extends Converter
1717
public function __construct(
1818
#[Config('feeds.converters.jsonl.options')]
1919
protected int $options,
20-
#[Config('feeds.pretty')]
21-
bool $pretty,
2220
TransformerService $transformer
2321
) {
24-
parent::__construct($pretty, $transformer);
22+
parent::__construct(false, $transformer);
2523

2624
$this->options &= ~JSON_PRETTY_PRINT;
2725
}

src/Enums/FeedFormatEnum.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@ enum FeedFormatEnum: string
99
case Xml = 'xml';
1010
case Json = 'json';
1111
case JsonLines = 'jsonl';
12+
case Csv = 'csv';
1213
}

src/Feeds/Feed.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,11 @@ public function chunkSize(): int
4343

4444
public function header(): string
4545
{
46-
return match ($this->format()) {
47-
FeedFormatEnum::Xml => '<?xml version="1.0" encoding="UTF-8"?>',
48-
default => ''
49-
};
46+
if ($this->format() !== FeedFormatEnum::Xml) {
47+
return '';
48+
}
49+
50+
return '<?xml version="1.0" encoding="UTF-8"?>';
5051
}
5152

5253
public function footer(): string

src/Helpers/ConverterHelper.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace DragonCode\LaravelFeed\Helpers;
66

77
use DragonCode\LaravelFeed\Converters\Converter;
8+
use DragonCode\LaravelFeed\Converters\CsvConverter;
89
use DragonCode\LaravelFeed\Converters\JsonConverter;
910
use DragonCode\LaravelFeed\Converters\JsonLinesConverter;
1011
use DragonCode\LaravelFeed\Converters\XmlConverter;
@@ -20,6 +21,7 @@ public function get(FeedFormatEnum $format): Converter
2021
FeedFormatEnum::Xml => app(XmlConverter::class),
2122
FeedFormatEnum::Json => app(JsonConverter::class),
2223
FeedFormatEnum::JsonLines => app(JsonLinesConverter::class),
24+
FeedFormatEnum::Csv => app(CsvConverter::class),
2325
};
2426
}
2527
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
1;Some 1;Some content 1;2025-09-04T04:08:12.000000Z;2025-09-04T04:08:12.000000Z
2+
2;Some 2;Some content 2;2025-09-04T04:08:12.000000Z;2025-09-04T04:08:12.000000Z
3+
3;Some 3;Some content 3;2025-09-04T04:08:12.000000Z;2025-09-04T04:08:12.000000Z

0 commit comments

Comments
 (0)