DocumentEndpoint::retrieveFiles()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 17
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 8
nc 4
nop 1
dl 0
loc 17
rs 10
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * This file is part of datamolino client.
5
 *
6
 * (c) 2018 cwd.at GmbH <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Cwd\Datamolino\Endpoints;
15
16
use Cwd\Datamolino\Model\Document;
17
use Cwd\Datamolino\Model\DocumentFile;
18
use Cwd\Datamolino\Model\OriginalFile;
19
use Cwd\Datamolino\Model\UploadFile;
20
use Symfony\Component\Finder\Finder;
21
use Symfony\Component\HttpFoundation\File\File as FileInfo;
22
use Webmozart\Assert\Assert;
23
24
class DocumentEndpoint extends AbstractEndpoint
25
{
26
    public const PAYLOAD_LIMIT = 1024 * 1024 * 20; // 20MB
27
    const ENDPOINT = 'documents';
28
29
    /**
30
     * @param string|array|Finder $source    Location of Files or Finder Instance or array of SPLFileInfo
31
     * @param int                 $agendaId
32
     * @param string              $type
33
     * @param bool                $fileSplit
34
     * @param bool                $lacyLoad
35
     *
36
     * @return Document[]
37
     *
38
     * @throws \Http\Client\Exception
39
     * @throws \LogicException
40
     */
41
    public function createMultiple($source, int $agendaId, string $type = Document::DOCTYPE_PURCHASE, $fileSplit = false, $lacyLoad = false): array
42
    {
43
        $currentFileSize = 0;
44
        $resultDocuments = [];
45
        $documentFiles = [];
46
47
        $files = $this->retrieveFiles($source);
48
49
        foreach ($files as $file) {
50
            $documentFile = new DocumentFile();
51
            $documentFile->setType($type)
52
                ->setAgendaId($agendaId)
53
                ->setFileSplit($fileSplit);
54
55
            $mimeType = (new FileInfo($file->getPathname()))->getMimeType();
56
            $currentFileSize += $file->getSize();
57
            $documentFile->setFile(
58
                new UploadFile($file->getFilename(), $mimeType, file_get_contents($file->getPathname()))
59
            );
60
61
            $documentFiles[] = $documentFile;
62
63
            if ($currentFileSize >= self::PAYLOAD_LIMIT) {
64
                $resultDocuments += $this->send($documentFiles, $lacyLoad);
65
                $documentFiles = [];
66
            }
67
        }
68
69
        if (count($documentFiles) > 0) {
70
            $resultDocuments += $this->send($documentFiles, $lacyLoad);
71
        }
72
73
        return $resultDocuments;
74
    }
75
76
    /**
77
     * @param string $fileUri
78
     * @param int    $agendaId
79
     * @param string $filename
80
     * @param string $type
81
     * @param bool   $fileSplit
82
     * @param bool   $lacyLoad
83
     *
84
     * @return Document
85
     *
86
     * @throws \Http\Client\Exception
87
     */
88
    public function create($fileUri, $agendaId, $filename, $type = Document::DOCTYPE_PURCHASE, $fileSplit = false, $lacyLoad = false): Document
89
    {
90
        $file = new FileInfo($fileUri);
91
        $mimeType = $file->getMimeType();
92
93
        $documentFile = new DocumentFile();
94
        $documentFile->setType($type)
95
            ->setAgendaId($agendaId)
96
            ->setFileSplit($fileSplit)
97
            ->setFile(
98
                new UploadFile($file->getFilename(), $mimeType, file_get_contents($file->getPathname()))
99
            )
100
        ;
101
102
        return current($this->send([$documentFile], $lacyLoad));
103
    }
104
105
    /**
106
     * @param DocumentFile[] $files
107
     *
108
     * @return array
109
     *
110
     * @throws \Http\Client\Exception
111
     */
112
    public function send(array $files, $lacyLoad = true)
113
    {
114
        $payload = $this->getClient()->getSerializer()->serialize(['documents' => $files], 'json');
115
        $documents = $this->getClient()->call($payload, null, self::ENDPOINT, Document::class, true, 'POST');
116
117
        if ($lacyLoad) {
118
            $ids = [];
119
            /** @var Document $document */
120
            foreach ($documents as $document) {
121
                if (null === $document->getId()) {
122
                    continue;
123
                }
124
                $ids[] = $document->getId();
125
            }
126
127
            if (0 == count($ids)) {
128
                return [];
129
            }
130
131
            return $this->find(current($files)->getAgendaId(), $ids);
132
        }
133
134
        return $documents;
135
    }
136
137
    /**
138
     * @param int $id
139
     *
140
     * @return Document|Document[]
141
     *
142
     * @throws \Http\Client\Exception
143
     */
144
    public function get(int $id)
145
    {
146
        $documents = $this->getClient()->call(null, $id, self::ENDPOINT, Document::class, true, 'GET');
147
148
        if (1 == count($documents)) {
149
            return current($documents);
150
        }
151
152
        return $documents;
153
    }
154
155
    /**
156
     * @param $document
157
     *
158
     * @return OriginalFile
159
     *
160
     * @throws \Http\Client\Exception
161
     */
162
    public function getOriginalFile($document): OriginalFile
163
    {
164
        if ($document instanceof Document) {
165
            $document = $document->getId();
166
        }
167
168
        return $this->getClient()->call(null, $document, self::ENDPOINT, OriginalFile::class, false, 'GET', '/original_file');
169
    }
170
171
    /**
172
     * @param int|Document $document
173
     *
174
     * @throws \Http\Client\Exception
175
     */
176
    public function delete($document): void
177
    {
178
        if ($document instanceof Document) {
179
            $document = $document->getId();
180
        }
181
182
        $this->getClient()->call(null, $document, self::ENDPOINT, null, false, 'DELETE');
183
    }
184
185
    /**
186
     * @param Document|int $document
187
     * @param string       $text
188
     *
189
     * @throws \Http\Client\Exception
190
     */
191
    public function repair($document, $text): void
192
    {
193
        if ($document instanceof Document) {
194
            $document = $document->getId();
195
        }
196
197
        $this->getClient()->call(null, $document, self::ENDPOINT, OriginalFile::class, false, 'POST', sprintf(
198
                '/repair?repair_description=%s', urlencode($text))
199
        );
200
    }
201
202
    /**
203
     * @param int            $agendaId
204
     * @param array          $ids
205
     * @param \DateTime|null $modifiedSince
206
     * @param array          $states
207
     * @param int            $page
208
     * @param string         $type
209
     *
210
     * @return mixed
211
     *
212
     * @throws \Http\Client\Exception
213
     */
214
    public function find($agendaId, array $ids = [], ?\DateTime $modifiedSince = null, array $states = [], $page = 1, $type = Document::DOCTYPE_PURCHASE)
215
    {
216
        $queryString = [
217
            sprintf('agenda_id=%s', $agendaId),
218
            sprintf('page=%s', $page),
219
            sprintf('type=%s', $type),
220
        ];
221
222
        if (null !== $modifiedSince) {
223
            $queryString[] = sprintf('modified_since=%s', $modifiedSince->format('Y-m-d\TH:i:s\Z'));
224
        }
225
226
        if (count($states) > 0) {
227
            foreach ($states as $state) {
228
                $queryString[] = sprintf('states[]=%s', $state);
229
            }
230
        }
231
232
        if (count($ids) > 0) {
233
            foreach ($ids as $id) {
234
                $queryString[] = sprintf('ids[]=%s', $id);
235
            }
236
        }
237
238
        return $this->getClient()->call(null, sprintf('?%s', implode('&', $queryString)), self::ENDPOINT, Document::class, true, 'GET');
239
    }
240
241
    /**
242
     * @param string|array|Finder $filesProvider Location of Files or Finder Instance or array of SPLFileInfo
243
     *
244
     * @throws \LogicException
245
     *
246
     * @return \SplFileInfo[]
247
     */
248
    private function retrieveFiles($filesProvider): iterable
249
    {
250
        if ($filesProvider instanceof Finder) {
251
            return $filesProvider->files();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $filesProvider->files() returns the type Symfony\Component\Finder\Finder which is incompatible with the documented return type SplFileInfo[].
Loading history...
252
        }
253
254
        if (is_string($filesProvider)) {
255
            return (new Finder())->in($filesProvider)->files();
0 ignored issues
show
Bug Best Practice introduced by
The expression return new Symfony\Compo...filesProvider)->files() returns the type Symfony\Component\Finder\Finder which is incompatible with the documented return type SplFileInfo[].
Loading history...
256
        }
257
258
        if (is_array($filesProvider)) {
0 ignored issues
show
introduced by
The condition is_array($filesProvider) is always true.
Loading history...
259
            Assert::allIsInstanceOf($filesProvider, \SplFileInfo::class, 'When using array all files need to implement SPLFileInfo');
260
261
            return $filesProvider;
262
        }
263
264
        throw new \LogicException(sprintf('Invalid files provider type: "%s', gettype($filesProvider)));
265
    }
266
}
267