Passed
Push — master ( a707ad...480443 )
by Jan
05:15
created

SEPAXMLExportResult::getGroupUlid()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
1
<?php
2
/*
3
 * Copyright (C) 2020  Jan Böhmer
4
 *
5
 * This program is free software: you can redistribute it and/or modify
6
 * it under the terms of the GNU Affero General Public License as published
7
 * by the Free Software Foundation, either version 3 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU Affero General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU Affero General Public License
16
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
17
 */
18
19
namespace App\Helpers\SEPAXML;
20
21
use App\Entity\SEPAExport;
22
use App\Helpers\ZIPBinaryFileResponseFacade;
23
use Doctrine\ORM\EntityManagerInterface;
24
use Symfony\Component\HttpFoundation\BinaryFileResponse;
25
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
26
use Symfony\Component\Uid\Ulid;
27
28
final class SEPAXMLExportResult implements \Countable
29
{
30
    /** @var SEPAExport[] */
31
    private $sepa_exports;
32
33
    /** @var Ulid */
34
    private $group_ulid;
35
36
    /**
37
     * @param  SEPAExport[]  $sepa_exports
38
     */
39
    public function __construct(array $sepa_exports)
40
    {
41
        if (count($sepa_exports) === 0) {
42
            throw new \InvalidArgumentException('$sepa_exports must not be empty!');
43
        }
44
45
        //Perform some checks on the sepa exports
46
        foreach($sepa_exports as $sepa_export) {
47
            if (!$sepa_export instanceof SEPAExport) {
48
                throw new \InvalidArgumentException('$sepa_exports must all be of type SEPAExport!');
49
            }
50
            if ($sepa_export->getXmlFile() === null) {
51
                throw new \InvalidArgumentException('Every Export in $sepa_exports must have an associated XML file!');
52
            }
53
        }
54
55
        $this->sepa_exports = $sepa_exports;
56
        $this->group_ulid = Ulid::generate();
0 ignored issues
show
Documentation Bug introduced by
It seems like Symfony\Component\Uid\Ulid::generate() of type string is incompatible with the declared type Symfony\Component\Uid\Ulid of property $group_ulid.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
57
58
        //Apply group ulid to all SEPA exports
59
        foreach ($this->sepa_exports as $export) {
60
            $export->setGroupUlid($this->group_ulid);
0 ignored issues
show
Bug introduced by
$this->group_ulid of type string is incompatible with the type Symfony\Component\Uid\Ulid|null expected by parameter $group_ulid of App\Entity\SEPAExport::setGroupUlid(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

60
            $export->setGroupUlid(/** @scrutinizer ignore-type */ $this->group_ulid);
Loading history...
61
        }
62
    }
63
64
    public function getGroupUlid(): Ulid
65
    {
66
        return $this->group_ulid;
67
    }
68
69
    /**
70
     * Returns the number of SEPAExports contained
71
     * @return int|void
72
     */
73
    public function count()
74
    {
75
        return count($this->sepa_exports);
76
    }
77
78
79
    /**
80
     * Returns the SEPA Exports contained in this result
81
     * @return SEPAExport[]
82
     */
83
    public function getSEPAExports(): array
84
    {
85
        return $this->sepa_exports;
86
    }
87
88
    /**
89
     * Returns an array of all XML files contained in this result.
90
     * The array keys contains suggested filenames for the files
91
     * @return \SplFileInfo[]
92
     */
93
    public function getXMLFiles(): array
94
    {
95
        $result = [];
96
97
        foreach ($this->sepa_exports as $sepa_export) {
98
            $filename = $this->generateFilename($sepa_export);
99
            //Ensure that filename is not existing yet (add an increment suffix)
100
            $i = 2;
101
            while (isset($result[$filename])) {
102
                $filename = basename($filename) . '_' . sprintf("%d", $i++) . '.xml';
103
            }
104
            $result[$filename] = $sepa_export->getXmlFile();
105
        }
106
107
        return $result;
108
    }
109
110
    /**
111
     * Returns an array of the contained XML files as strings.
112
     * The array keys contains suggested filenames for the files.
113
     * @return string[]
114
     */
115
    public function getXMLString(): array
116
    {
117
        $result = [];
118
        $files = $this->getXMLFiles();
119
120
        foreach ($files as $filename => $file) {
121
            $result[$filename] = file_get_contents($file->getPathname());
122
        }
123
124
        return $result;
125
    }
126
127
    /**
128
     * Generates a download response for the contained XML files. If only a single XML is contained, it will be downloaded
129
     * as XML file, otherwise as ZIP containing all files.
130
     * @param  string  $disposition_filename
131
     * @param  bool  $force_zip
132
     * @return BinaryFileResponse
133
     */
134
    public function getDownloadResponse(string $disposition_filename, bool $force_zip = false): BinaryFileResponse
135
    {
136
        //If we have only one file, we can just return the file
137
        if ($force_zip === false && $this->count() === 1) {
138
            $response = new BinaryFileResponse($this->sepa_exports[0]);
0 ignored issues
show
Bug introduced by
$this->sepa_exports[0] of type App\Entity\SEPAExport is incompatible with the type SplFileInfo|string expected by parameter $file of Symfony\Component\HttpFo...Response::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

138
            $response = new BinaryFileResponse(/** @scrutinizer ignore-type */ $this->sepa_exports[0]);
Loading history...
139
            $response->setPrivate();
140
            $response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, $disposition_filename);
141
        } else { //Otherwise we download the file as ZIP
142
            $response = ZIPBinaryFileResponseFacade::createZIPResponseFromFiles($this->getXMLFiles(), $disposition_filename);
143
        }
144
145
        return $response;
146
    }
147
148
    /**
149
     * Persist all contained SEPAExport entities using the given EntityManager.
150
     * @param  EntityManagerInterface  $entityManager
151
     * @return void
152
     */
153
    public function persistSEPAExports(EntityManagerInterface $entityManager): void
154
    {
155
        foreach($this->sepa_exports as $sepa_export) {
156
            $entityManager->persist($sepa_export);
157
        }
158
    }
159
160
    private function generateFilename(SEPAExport $export): string
161
    {
162
        return $export->getDescription() . '_' . $export->getCreationDate()->format('Y-m-d-His') . '.xml';
163
    }
164
}