Completed
Push — master ( 3e0714...50ebf9 )
by Gabriel
09:17
created

PdfLetterTrait::hydrateMediaRepositoryCustom()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 4
cts 4
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
namespace ByTIC\DocumentGenerator\PdfLetters;
4
5
use ByTIC\DocumentGenerator\Helpers;
6
use ByTIC\DocumentGenerator\PdfLetters\Fields\FieldTrait;
7
use ByTIC\MediaLibrary\Exceptions\FileCannotBeAdded\FileUnacceptableForCollection;
8
use ByTIC\MediaLibrary\FileAdder\FileAdderFactory;
9
use ByTIC\MediaLibrary\HasMedia\HasMediaTrait;
10
use ByTIC\MediaLibrary\HasMedia\Interfaces\HasMedia;
11
use ByTIC\MediaLibrary\Media\Media;
12
use ByTIC\MediaLibrary\MediaRepository\MediaRepository;
13
use Nip\Records\RecordManager;
14
use Symfony\Component\HttpFoundation\File\UploadedFile;
15
use Nip\Records\Traits\AbstractTrait\RecordTrait as AbstractRecordTrait;
16
use setasign\Fpdi;
17
use TCPDF;
18
19
/**
20
 * Class PdfLetterTrait
21
 * @package ByTIC\DocumentGenerator\PdfLetters
22
 *
23
 * @method FieldTrait[] getCustomFields()
24
 *
25
 * @property int $id_item
26
 * @property string $type
27
 * @property string $orientation
28
 * @property string $format
29
 */
30
trait PdfLetterTrait
31
{
32
    use AbstractRecordTrait;
33
    use HasMediaTrait;
34
35
    /**
36
     * @return string
37
     */
38
    public function getName()
39
    {
40
        return $this->getManager()->getLabel('title.singular') . ' #' . $this->id;
41
    }
42
43
    /**
44
     * @return bool
45
     */
46
    public function hasFile()
47
    {
48
        $file = $this->getFile();
49
50
        return $file instanceof Media;
51
    }
52
53
    /**
54
     * @return bool|Media
55
     */
56 1
    public function getFile()
57
    {
58 1
        $files = $this->getFiles();
59 1
        if (count($files) < 1) {
60
            return false;
61
        }
62
63 1
        return $files->getDefaultMedia();
64
    }
65
66
    /**
67
     * @return mixed
68
     */
69
    public function delete()
70
    {
71
        $this->deleteLetters();
72
73
        /** @noinspection PhpUndefinedClassInspection */
74
        return parent::delete();
75
    }
76
77
    public function deleteLetters()
78
    {
79
        $this->getFiles()->delete();
80
    }
81
82
    public function downloadExample()
83
    {
84
        $result = $this->getModelExample();
85
        /** @noinspection PhpUndefinedFieldInspection */
86
        $result->demo = true;
0 ignored issues
show
Bug introduced by
The property demo does not seem to exist in Nip\Records\Traits\AbstractTrait\RecordTrait.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
87
88
        $this->download($result);
89
    }
90
91
    /**
92
     * @return AbstractRecordTrait
0 ignored issues
show
Comprehensibility Bug introduced by
The return type AbstractRecordTrait is a trait, and thus cannot be used for type-hinting in PHP. Maybe consider adding an interface and use that for type-hinting?

In PHP traits cannot be used for type-hinting as they do not define a well-defined structure. This is because any class that uses a trait can rename that trait’s methods.

If you would like to return an object that has a guaranteed set of methods, you could create a companion interface that lists these methods explicitly.

Loading history...
93
     */
94
    abstract public function getModelExample();
95
96
    /**
97
     * @param AbstractRecordTrait $model
0 ignored issues
show
introduced by
The type AbstractRecordTrait for parameter $model is a trait, and thus cannot be used for type-hinting in PHP. Maybe consider adding an interface and use that for type-hinting?
Loading history...
98
     */
99
    public function download($model)
100
    {
101
        $pdf = $this->generatePdfObj($model);
102
103
        $pdf->Output($this->getFileNameFromModel($model) . '.pdf', 'D');
104
        die();
105
    }
106
107
    public function downloadBlank()
108
    {
109
        $file = $this->getFile();
110
        $model = $this->getModelExample();
111
        $name = $this->getFileNameFromModel($model) . '.pdf';
112
113
        header('Content-Type: application/pdf');
114
        header('Content-Description: File Transfer');
115
        header('Cache-Control: private, must-revalidate, post-check=0, pre-check=0, max-age=1');
116
        header('Pragma: public');
117
        header('Expires: Sat, 26 Jul 1997 05:00:00 GMT'); // Date in the past
118
        header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
119
        header('Content-Disposition: attachment; filename="' . $name . '";');
120
        header("Content-Transfer-Encoding: Binary");
121
        echo $file->read();
122
        die();
123
    }
124
125
    /**
126
     * @param $model
127
     * @param $output
128
     * @return bool|Fpdi|TCPDF
129
     */
130
    public function generateFile($model, $output = null)
131
    {
132
        $pdf = $this->generatePdfObj($model);
133
134
        if ($model->demo === true) {
135
            $this->pdfDrawGuidelines($pdf);
136
        }
137
        $fileName = $this->getFileNameFromModel($model) . '.pdf';
138
        if (is_dir($output)) {
139
            return $pdf->Output($output . $fileName, 'F');
140
        }
141
        if ($output instanceof HasMedia) {
142
            /** @var HasMediaTrait $output */
143
            $output->addFileFromContent(
144
                $pdf->Output($fileName, 'S'),
145
                $fileName
146
            );
147
        }
148
        return $pdf;
149
    }
150
151
    /**
152
     * @param AbstractRecordTrait $model
0 ignored issues
show
introduced by
The type AbstractRecordTrait for parameter $model is a trait, and thus cannot be used for type-hinting in PHP. Maybe consider adding an interface and use that for type-hinting?
Loading history...
153
     * @return FPDI|TCPDF
154
     */
155
    public function generatePdfObj($model)
156
    {
157
        $pdf = $this->generateNewPdfObj();
158
159
        /** @noinspection PhpUndefinedFieldInspection */
160
        if ($model->demo === true) {
0 ignored issues
show
Bug introduced by
The property demo does not seem to exist in Nip\Records\Traits\AbstractTrait\RecordTrait.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
161
            $this->pdfDrawGuidelines($pdf);
162
        }
163
164
        $this->addFieldsToPDF($pdf, $model);
165
166
        return $pdf;
167
    }
168
169
    /**
170
     * @param $pdf
171
     * @param $model
172
     */
173
    protected function addFieldsToPDF($pdf, $model)
174
    {
175
176
        /** @var FieldTrait[] $fields */
177
        $fields = $this->getCustomFields();
178
        foreach ($fields as $field) {
179
            $field->addToPdf($pdf, $model);
180
        }
181
    }
182
183
    /**
184
     * @return FPDI|TCPDF
185
     */
186 1
    public function generateNewPdfObj()
187
    {
188
        /** @var Fpdi|TCPDF $pdf */
189 1
        $pdf = new Fpdi\TcpdfFpdi('L');
0 ignored issues
show
Deprecated Code introduced by
The class setasign\Fpdi\TcpdfFpdi has been deprecated with message: Class was moved to \setasign\Fpdi\Tcpdf\Fpdi

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
190 1
        $pdf->setPrintHeader(false);
191 1
        $pdf->SetCreator(PDF_CREATOR);
192
193 1
        $pdf->SetAuthor(Helpers::author());
194
195 1
        $mediaFile = $this->getFile();
196 1
        $pageCount = $pdf->setSourceFile($mediaFile->getFile()->readStream());
197 1
        for ($pageNo = 1; $pageNo <= $pageCount; $pageNo++) {
198 1
            $tplidx = $pdf->importPage($pageNo, '/MediaBox');
199
200 1
            $pdf->addPage(ucfirst($this->orientation), $this->format);
201 1
            $pdf->useTemplate($tplidx);
202 1
            $pdf->endPage();
203
        }
204 1
        $pdf->setPage(1);
205
206 1
        return $pdf;
207
    }
208
209
    /**
210
     * @return AbstractRecordTrait
0 ignored issues
show
Comprehensibility Bug introduced by
The return type AbstractRecordTrait is a trait, and thus cannot be used for type-hinting in PHP. Maybe consider adding an interface and use that for type-hinting?

In PHP traits cannot be used for type-hinting as they do not define a well-defined structure. This is because any class that uses a trait can rename that trait’s methods.

If you would like to return an object that has a guaranteed set of methods, you could create a companion interface that lists these methods explicitly.

Loading history...
211
     */
212
    public function getItem()
213
    {
214
        $manager = $this->getItemsManager();
215
216
        return $manager->findOne($this->id_item);
0 ignored issues
show
Bug introduced by
It seems like findOne() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
217
    }
218
219
    /**
220
     * @return AbstractRecordTrait
0 ignored issues
show
Comprehensibility Bug introduced by
The return type AbstractRecordTrait is a trait, and thus cannot be used for type-hinting in PHP. Maybe consider adding an interface and use that for type-hinting?

In PHP traits cannot be used for type-hinting as they do not define a well-defined structure. This is because any class that uses a trait can rename that trait’s methods.

If you would like to return an object that has a guaranteed set of methods, you could create a companion interface that lists these methods explicitly.

Loading history...
221
     */
222
    abstract public function getItemsManager();
223
224
    /**
225
     * @return string
226
     */
227
    protected function getFileNameDefault()
228
    {
229
        return 'letter';
230
    }
231
232
    /**
233
     * @param FPDI|TCPDF $pdf
234
     */
235
    protected function pdfDrawGuidelines($pdf)
236
    {
237
        for ($pos = 5; $pos < 791; $pos = $pos + 5) {
238
            if (($pos % 100) == 0) {
239
                $pdf->SetDrawColor(0, 0, 200);
240
                $pdf->SetLineWidth(.7);
241
            } elseif (($pos % 50) == 0) {
242
                $pdf->SetDrawColor(200, 0, 0);
243
                $pdf->SetLineWidth(.4);
244
            } else {
245
                $pdf->SetDrawColor(128, 128, 128);
246
                $pdf->SetLineWidth(.05);
247
            }
248
249
            $pdf->Line(0, $pos, 611, $pos);
250
            if ($pos < 611) {
251
                $pdf->Line($pos, 0, $pos, 791);
252
            }
253
        }
254
    }
255
256
    /** @noinspection PhpUnusedParameterInspection
257
     * @param $model
258
     * @return string
259
     */
260
    protected function getFileNameFromModel($model)
0 ignored issues
show
Unused Code introduced by
The parameter $model is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
261
    {
262
        return $this->getFileNameDefault();
263
    }
264
265
    /**
266
     * @param UploadedFile $uploadedFile
267
     * @return string|boolean
268
     */
269 2
    public function uploadFromRequest($uploadedFile)
270
    {
271 2
        $fileCollection = $this->getFiles();
272
273 2
        if (!$uploadedFile->isValid()) {
274
            return $uploadedFile->getErrorMessage();
275
        }
276
277
        try {
278 2
            $fileAdder = $this->addFile($uploadedFile);
279 1
            $newMedia = $fileAdder->getMedia();
280 1
        } catch (FileUnacceptableForCollection $exception) {
281 1
            return $exception->violations->getMessageString();
282
        }
283
284 1
        foreach ($fileCollection as $name => $media) {
285 1
            if ($name != $newMedia->getName()) {
286 1
                $media->delete();
287
            }
288
        }
289 1
        return $newMedia;
290
    }
291
292
    /**
293
     * @param MediaRepository $mediaRepository
294
     * @return MediaRepository
295
     */
296 3
    protected function hydrateMediaRepositoryCustom($mediaRepository)
297
    {
298 3
        $filesCollection = $mediaRepository->getCollection('files');
299 3
        $filesCollection->getConstraint()->mimeTypes = ['application/pdf'];
300 3
        return $mediaRepository;
301
    }
302
}
303