Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
96.77% covered (success)
96.77%
30 / 31
100.00% covered (success)
100.00%
3 / 3
CRAP
100.00% covered (success)
100.00%
1 / 1
ExportConfigDto
100.00% covered (success)
100.00%
30 / 30
100.00% covered (success)
100.00%
3 / 3
8
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 fromArray
100.00% covered (success)
100.00%
19 / 19
100.00% covered (success)
100.00%
1 / 1
6
 toArray
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5/** @license For full copyright and license information, please see the LICENSE.md file. */
6
7namespace App\Core\DataExchange\Domain\Model;
8
9defined('AMMONLY_APP') || exit('Direct script access is forbidden.');
10
11/**
12 * Value Object configuring tabular record export parameters and formats.
13 *
14 * @package App\Core\DataExchange\Domain\Model
15 */
16final readonly class ExportConfigDto
17{
18    public const string FORMAT_CSV = 'csv';
19    public const string FORMAT_XLSX = 'xlsx';
20
21    public const string SCOPE_SELECTED = 'selected';
22    public const string SCOPE_FILTERED = 'filtered';
23    public const string SCOPE_ALL = 'all';
24
25    /**
26     * ExportConfigDto constructor.
27     *
28     * @param string        $moduleName      Target module machine name.
29     * @param string        $format          Desired export format (csv, xlsx).
30     * @param string        $scope           Export record scope (selected, filtered, all).
31     * @param list<int>     $recordIds       Explicit IDs if scope is selected.
32     * @param list<string>  $selectedColumns Field keys to export (empty means all standard fields).
33     * @param string        $csvDelimiter    CSV cell delimiter character (, or ;).
34     * @param bool          $includeBom      Include UTF-8 Byte Order Mark for Excel compatibility.
35     * @param int|null      $filterId        Active DataGrid filter ID if scope is filtered.
36     */
37    public function __construct(
38        public string $moduleName,
39        public string $format = self::FORMAT_CSV,
40        public string $scope = self::SCOPE_ALL,
41        public array $recordIds = [],
42        public array $selectedColumns = [],
43        public string $csvDelimiter = ',',
44        public bool $includeBom = true,
45        public ?int $filterId = null
46    ) {
47    }
48
49    /**
50     * Creates an ExportConfigDto from raw array parameters.
51     *
52     * @param array<string, mixed> $data Request parameters.
53     * @return self Populated export configuration.
54     */
55    public static function fromArray(array $data): self
56    {
57        $rawIds = (array) ($data['record_ids'] ?? []);
58        $intIds = [];
59        foreach ($rawIds as $id) {
60            if (is_numeric($id) && (int) $id > 0) {
61                $intIds[] = (int) $id;
62            }
63        }
64
65        $rawColumns = (array) ($data['selected_columns'] ?? []);
66        $cleanColumns = array_values(array_filter(array_map('strval', $rawColumns)));
67
68        return new self(
69            moduleName:      (string) ($data['module_name'] ?? ''),
70            format:          (string) ($data['format'] ?? self::FORMAT_CSV),
71            scope:           (string) ($data['scope'] ?? self::SCOPE_ALL),
72            recordIds:       $intIds,
73            selectedColumns: $cleanColumns,
74            csvDelimiter:    (string) ($data['csv_delimiter'] ?? ','),
75            includeBom:      (bool) ($data['include_bom'] ?? true),
76            filterId:        isset($data['filter_id']) && is_numeric($data['filter_id'])
77                ? (int) $data['filter_id']
78                : null
79        );
80    }
81
82    /**
83     * Serializes configuration to array.
84     *
85     * @return array<string, mixed> Serialized parameters.
86     */
87    public function toArray(): array
88    {
89        return [
90            'module_name'      => $this->moduleName,
91            'format'           => $this->format,
92            'scope'            => $this->scope,
93            'record_ids'       => $this->recordIds,
94            'selected_columns' => $this->selectedColumns,
95            'csv_delimiter'    => $this->csvDelimiter,
96            'include_bom'      => $this->includeBom,
97            'filter_id'        => $this->filterId,
98        ];
99    }
100}