Passed
Push — develop ( 493714...dd5809 )
by nguereza
01:37
created

DocxTemplate   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 302
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 23
eloc 73
c 1
b 0
f 0
dl 0
loc 302
rs 10

17 Methods

Rating   Name   Duplication   Size   Complexity  
A cleanTempData() 0 4 1
A copyTemplateFileToTempDir() 0 9 1
A getConvertor() 0 3 1
A process() 0 16 3
A __construct() 0 11 1
A getExtractor() 0 3 1
A getData() 0 3 1
A convert() 0 7 1
A renderTemplate() 0 7 2
A extractDocumentFiles() 0 15 4
A setTemplateFile() 0 4 1
A setTempDir() 0 4 1
A setData() 0 4 1
A writeDocx() 0 5 1
A getOutputTemplateFile() 0 3 1
A getRenderer() 0 3 1
A getConversionFile() 0 3 1
1
<?php
2
3
/**
4
 * Platine Docx template
5
 *
6
 * Platine Docx template is the lightweight library to manipulate the content
7
 * of .docx files
8
 *
9
 * This content is released under the MIT License (MIT)
10
 *
11
 * Copyright (c) 2020 Platine Docx template
12
 *
13
 * Permission is hereby granted, free of charge, to any person obtaining a copy
14
 * of this software and associated documentation files (the "Software"), to deal
15
 * in the Software without restriction, including without limitation the rights
16
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17
 * copies of the Software, and to permit persons to whom the Software is
18
 * furnished to do so, subject to the following conditions:
19
 *
20
 * The above copyright notice and this permission notice shall be included in all
21
 * copies or substantial portions of the Software.
22
 *
23
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29
 * SOFTWARE.
30
 */
31
32
/**
33
 *  @file DocxTemplate.php
34
 *
35
 *  The Docx Template main class.
36
 *
37
 *  @package    Platine\DocxTemplate
38
 *  @author Platine Developers Team
39
 *  @copyright  Copyright (c) 2020
40
 *  @license    http://opensource.org/licenses/MIT  MIT License
41
 *  @link   http://www.iacademy.cf
42
 *  @version 1.0.0
43
 *  @filesource
44
 */
45
46
declare(strict_types=1);
47
48
namespace Platine\DocxTemplate;
49
50
use Platine\DocxTemplate\Archive\NullExtractor;
51
use Platine\DocxTemplate\Convertor\NullConvertor;
52
use Platine\DocxTemplate\Renderer\NullRenderer;
53
use Platine\Filesystem\Filesystem;
54
55
/**
56
 * @class DocxTemplate
57
 * @package Platine\DocxTemplate
58
 */
59
class DocxTemplate
60
{
61
62
    /**
63
     * The convertor instance to use
64
     * @var DocxConvertorInterface
65
     */
66
    protected DocxConvertorInterface $convertor;
67
68
    /**
69
     * The template renderer instance
70
     * @var DocxTemplateRendererInterface
71
     */
72
    protected DocxTemplateRendererInterface $renderer;
73
74
    /**
75
     * The template extractor instance
76
     * @var DocxExtractorInterface
77
     */
78
    protected DocxExtractorInterface $extractor;
79
80
    /**
81
     * The file instance to use
82
     * @var Filesystem
83
     */
84
    protected Filesystem $filesystem;
85
86
    /**
87
     * The data to use to replace template variables
88
     * @var array<string, mixed>
89
     */
90
    protected array $data = [];
91
92
    /**
93
     * The document template file
94
     * @var string
95
     */
96
    protected string $templateFile;
97
98
    /**
99
     * The template temporary file path
100
     * @var string
101
     */
102
    protected string $templateTempFile;
103
104
    /**
105
     * Output template file after renderer
106
     * @var string
107
     */
108
    protected string $outputTemplateFile = '';
109
110
    /**
111
     * The file path after conversion
112
     * @var string
113
     */
114
    protected string $conversionFile = '';
115
116
    /**
117
     * The list of files inside document template
118
     * @var array<string>
119
     */
120
    protected array $docxFileList = [];
121
122
    /**
123
     * The list of files pattern to use
124
     * @var array<string>
125
     */
126
    protected array $fileListToProcess = [
127
        'word/document.xml',
128
        'word/endnotes.xml',
129
        'word/footer*.xml',
130
        'word/footnotes.xml',
131
        'word/header*.xml',
132
    ];
133
134
    /**
135
     * Temporary directory to use to extract template
136
     * file into
137
     * @var string
138
     */
139
    protected string $tempDir;
140
141
    /**
142
     * The directory to use to extract template contents into
143
     * @var string
144
     */
145
    protected string $templateExtractDir;
146
147
    /**
148
     * Create new instance
149
     * @param Filesystem $filesystem
150
     * @param DocxTemplateRendererInterface|null $renderer
151
     * @param DocxConvertorInterface|null $convertor
152
     * @param DocxExtractorInterface|null $extractor
153
     */
154
    public function __construct(
155
        Filesystem $filesystem,
156
        ?DocxTemplateRendererInterface $renderer = null,
157
        ?DocxConvertorInterface $convertor = null,
158
        ?DocxExtractorInterface $extractor = null
159
    ) {
160
        $this->filesystem = $filesystem;
161
        $this->convertor = $convertor ?? new NullConvertor();
162
        $this->renderer = $renderer ?? new NullRenderer();
163
        $this->extractor = $extractor ?? new NullExtractor();
164
        $this->tempDir = sys_get_temp_dir();
165
    }
166
167
    /**
168
     * Return the convertor
169
     * @return DocxConvertorInterface
170
     */
171
    public function getConvertor(): DocxConvertorInterface
172
    {
173
        return $this->convertor;
174
    }
175
176
    /**
177
     * Return the renderer
178
     * @return DocxTemplateRendererInterface
179
     */
180
    public function getRenderer(): DocxTemplateRendererInterface
181
    {
182
        return $this->renderer;
183
    }
184
185
    /**
186
     * Return the extractor
187
     * @return DocxExtractorInterface
188
     */
189
    public function getExtractor(): DocxExtractorInterface
190
    {
191
        return $this->extractor;
192
    }
193
194
    /**
195
     * Return the output template file after processed
196
     * @return string
197
     */
198
    public function getOutputTemplateFile(): string
199
    {
200
        return $this->outputTemplateFile;
201
    }
202
203
    /**
204
     * Return the conversion file path or content
205
     * @return string
206
     */
207
    public function getConversionFile(): string
208
    {
209
        return $this->conversionFile;
210
    }
211
212
    /**
213
     * Return the data
214
     * @return array<string, mixed>
215
     */
216
    public function getData(): array
217
    {
218
        return $this->data;
219
    }
220
221
    /**
222
     * Set the data
223
     * @param array<string, mixed> $data
224
     * @return $this
225
     */
226
    public function setData(array $data): self
227
    {
228
        $this->data = $data;
229
        return $this;
230
    }
231
232
    /**
233
     * Set template file
234
     * @param string $templateFile
235
     * @return $this
236
     */
237
    public function setTemplateFile(string $templateFile): self
238
    {
239
        $this->templateFile = $templateFile;
240
        return $this;
241
    }
242
243
    /**
244
     * Set the template directory
245
     * @param string $tempDir
246
     * @return $this
247
     */
248
    public function setTempDir(string $tempDir): self
249
    {
250
        $this->tempDir = $tempDir;
251
        return $this;
252
    }
253
254
255
    /**
256
     * Process the document template
257
     * @return void
258
     */
259
    public function process(): void
260
    {
261
        $this->copyTemplateFileToTempDir();
262
        $this->extractDocumentFiles();
263
        foreach ($this->docxFileList as $file) {
264
            $this->renderTemplate($file);
265
        }
266
267
        if (empty($this->outputTemplateFile)) {
268
            $this->outputTemplateFile = $this->tempDir
269
                                        . '/output_' . basename($this->templateFile);
270
        }
271
272
        $this->writeDocx();
273
274
        $this->cleanTempData();
275
    }
276
277
    /**
278
     * Convert the output template to another format like PDF, HTML
279
     * @return $this
280
     */
281
    public function convert(): self
282
    {
283
        $this->conversionFile = $this->convertor->convert(
284
            $this->outputTemplateFile
285
        );
286
287
        return $this;
288
    }
289
290
    /**
291
     * Copy the template file to temporary directory
292
     * @return void
293
     */
294
    protected function copyTemplateFileToTempDir(): void
295
    {
296
        $templateFile = $this->filesystem->file($this->templateFile);
297
        $this->templateTempFile = $templateFile->copyTo($this->tempDir)->getPath();
298
299
        $tempDir = $this->filesystem->directory($this->tempDir);
300
        $extractDir = $tempDir->create('tmp_extract_' . uniqid());
301
302
        $this->templateExtractDir = $extractDir->getPath();
303
    }
304
305
    /**
306
     * Extract template document file
307
     * @return void
308
     */
309
    protected function extractDocumentFiles(): void
310
    {
311
        $fileList = [];
312
        $this->extractor->extract($this->templateTempFile, $this->templateExtractDir);
313
        $total = $this->extractor->totalFiles();
314
        for ($i = 0; $i < $total; $i++) {
315
            $info = $this->extractor->getInfo($i);
316
            foreach ($this->fileListToProcess as $fileToProcess) {
317
                if (fnmatch($fileToProcess, $info->getName())) {
318
                    $fileList[] = $info->getName();
319
                }
320
            }
321
        }
322
        $this->docxFileList = $fileList;
323
        $this->extractor->close();
324
    }
325
326
    /**
327
     * Write template document back after processed
328
     * @return void
329
     */
330
    protected function writeDocx(): void
331
    {
332
        $this->extractor->archiveFolder(
333
            $this->templateExtractDir,
334
            $this->outputTemplateFile
335
        );
336
    }
337
338
    /**
339
     * Render the template (replace variables)
340
     * @param string $file
341
     * @return void
342
     */
343
    protected function renderTemplate(string $file): void
344
    {
345
        $templateFile = $this->filesystem->file($this->templateExtractDir . '/' . $file);
346
        if ($templateFile->exists()) {
347
            $content = $templateFile->read();
348
            $renderContent = $this->renderer->render($content, $this->data);
349
            $templateFile->write($renderContent);
350
        }
351
    }
352
353
    /**
354
     * Clean the temporary data after processed
355
     * @return void
356
     */
357
    protected function cleanTempData(): void
358
    {
359
        $this->filesystem->directory($this->templateExtractDir)->delete();
360
        $this->filesystem->file($this->templateTempFile)->delete();
361
    }
362
}
363