DocxTemplate   A
last analyzed

Complexity

Total Complexity 23

Size/Duplication

Total Lines 301
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 301
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   https://www.platine-php.com
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
     * The convertor instance to use
63
     * @var DocxConvertorInterface
64
     */
65
    protected DocxConvertorInterface $convertor;
66
67
    /**
68
     * The template renderer instance
69
     * @var DocxTemplateRendererInterface
70
     */
71
    protected DocxTemplateRendererInterface $renderer;
72
73
    /**
74
     * The template extractor instance
75
     * @var DocxExtractorInterface
76
     */
77
    protected DocxExtractorInterface $extractor;
78
79
    /**
80
     * The file instance to use
81
     * @var Filesystem
82
     */
83
    protected Filesystem $filesystem;
84
85
    /**
86
     * The data to use to replace template variables
87
     * @var array<string, mixed>
88
     */
89
    protected array $data = [];
90
91
    /**
92
     * The document template file
93
     * @var string
94
     */
95
    protected string $templateFile;
96
97
    /**
98
     * The template temporary file path
99
     * @var string
100
     */
101
    protected string $templateTempFile;
102
103
    /**
104
     * Output template file after renderer
105
     * @var string
106
     */
107
    protected string $outputTemplateFile = '';
108
109
    /**
110
     * The file path after conversion
111
     * @var string
112
     */
113
    protected string $conversionFile = '';
114
115
    /**
116
     * The list of files inside document template
117
     * @var array<string>
118
     */
119
    protected array $docxFileList = [];
120
121
    /**
122
     * The list of files pattern to use
123
     * @var array<string>
124
     */
125
    protected array $fileListToProcess = [
126
        'word/document.xml',
127
        'word/endnotes.xml',
128
        'word/footer*.xml',
129
        'word/footnotes.xml',
130
        'word/header*.xml',
131
    ];
132
133
    /**
134
     * Temporary directory to use to extract template
135
     * file into
136
     * @var string
137
     */
138
    protected string $tempDir;
139
140
    /**
141
     * The directory to use to extract template contents into
142
     * @var string
143
     */
144
    protected string $templateExtractDir;
145
146
    /**
147
     * Create new instance
148
     * @param Filesystem $filesystem
149
     * @param DocxTemplateRendererInterface|null $renderer
150
     * @param DocxConvertorInterface|null $convertor
151
     * @param DocxExtractorInterface|null $extractor
152
     */
153
    public function __construct(
154
        Filesystem $filesystem,
155
        ?DocxTemplateRendererInterface $renderer = null,
156
        ?DocxConvertorInterface $convertor = null,
157
        ?DocxExtractorInterface $extractor = null
158
    ) {
159
        $this->filesystem = $filesystem;
160
        $this->convertor = $convertor ?? new NullConvertor();
161
        $this->renderer = $renderer ?? new NullRenderer();
162
        $this->extractor = $extractor ?? new NullExtractor();
163
        $this->tempDir = sys_get_temp_dir();
164
    }
165
166
    /**
167
     * Return the convertor
168
     * @return DocxConvertorInterface
169
     */
170
    public function getConvertor(): DocxConvertorInterface
171
    {
172
        return $this->convertor;
173
    }
174
175
    /**
176
     * Return the renderer
177
     * @return DocxTemplateRendererInterface
178
     */
179
    public function getRenderer(): DocxTemplateRendererInterface
180
    {
181
        return $this->renderer;
182
    }
183
184
    /**
185
     * Return the extractor
186
     * @return DocxExtractorInterface
187
     */
188
    public function getExtractor(): DocxExtractorInterface
189
    {
190
        return $this->extractor;
191
    }
192
193
    /**
194
     * Return the output template file after processed
195
     * @return string
196
     */
197
    public function getOutputTemplateFile(): string
198
    {
199
        return $this->outputTemplateFile;
200
    }
201
202
    /**
203
     * Return the conversion file path or content
204
     * @return string
205
     */
206
    public function getConversionFile(): string
207
    {
208
        return $this->conversionFile;
209
    }
210
211
    /**
212
     * Return the data
213
     * @return array<string, mixed>
214
     */
215
    public function getData(): array
216
    {
217
        return $this->data;
218
    }
219
220
    /**
221
     * Set the data
222
     * @param array<string, mixed> $data
223
     * @return $this
224
     */
225
    public function setData(array $data): self
226
    {
227
        $this->data = $data;
228
        return $this;
229
    }
230
231
    /**
232
     * Set template file
233
     * @param string $templateFile
234
     * @return $this
235
     */
236
    public function setTemplateFile(string $templateFile): self
237
    {
238
        $this->templateFile = $templateFile;
239
        return $this;
240
    }
241
242
    /**
243
     * Set the template directory
244
     * @param string $tempDir
245
     * @return $this
246
     */
247
    public function setTempDir(string $tempDir): self
248
    {
249
        $this->tempDir = $tempDir;
250
        return $this;
251
    }
252
253
254
    /**
255
     * Process the document template
256
     * @return void
257
     */
258
    public function process(): void
259
    {
260
        $this->copyTemplateFileToTempDir();
261
        $this->extractDocumentFiles();
262
        foreach ($this->docxFileList as $file) {
263
            $this->renderTemplate($file);
264
        }
265
266
        if (empty($this->outputTemplateFile)) {
267
            $this->outputTemplateFile = $this->tempDir
268
                                        . '/output_' . basename($this->templateFile);
269
        }
270
271
        $this->writeDocx();
272
273
        $this->cleanTempData();
274
    }
275
276
    /**
277
     * Convert the output template to another format like PDF, HTML
278
     * @return $this
279
     */
280
    public function convert(): self
281
    {
282
        $this->conversionFile = $this->convertor->convert(
283
            $this->outputTemplateFile
284
        );
285
286
        return $this;
287
    }
288
289
    /**
290
     * Copy the template file to temporary directory
291
     * @return void
292
     */
293
    protected function copyTemplateFileToTempDir(): void
294
    {
295
        $templateFile = $this->filesystem->file($this->templateFile);
296
        $this->templateTempFile = $templateFile->copyTo($this->tempDir)->getPath();
297
298
        $tempDir = $this->filesystem->directory($this->tempDir);
299
        $extractDir = $tempDir->create('tmp_extract_' . uniqid());
300
301
        $this->templateExtractDir = $extractDir->getPath();
302
    }
303
304
    /**
305
     * Extract template document file
306
     * @return void
307
     */
308
    protected function extractDocumentFiles(): void
309
    {
310
        $fileList = [];
311
        $this->extractor->extract($this->templateTempFile, $this->templateExtractDir);
312
        $total = $this->extractor->totalFiles();
313
        for ($i = 0; $i < $total; $i++) {
314
            $info = $this->extractor->getInfo($i);
315
            foreach ($this->fileListToProcess as $fileToProcess) {
316
                if (fnmatch($fileToProcess, $info->getName())) {
317
                    $fileList[] = $info->getName();
318
                }
319
            }
320
        }
321
        $this->docxFileList = $fileList;
322
        $this->extractor->close();
323
    }
324
325
    /**
326
     * Write template document back after processed
327
     * @return void
328
     */
329
    protected function writeDocx(): void
330
    {
331
        $this->extractor->archiveFolder(
332
            $this->templateExtractDir,
333
            $this->outputTemplateFile
334
        );
335
    }
336
337
    /**
338
     * Render the template (replace variables)
339
     * @param string $file
340
     * @return void
341
     */
342
    protected function renderTemplate(string $file): void
343
    {
344
        $templateFile = $this->filesystem->file($this->templateExtractDir . '/' . $file);
345
        if ($templateFile->exists()) {
346
            $content = $templateFile->read();
347
            $renderContent = $this->renderer->render($content, $this->data);
348
            $templateFile->write($renderContent);
349
        }
350
    }
351
352
    /**
353
     * Clean the temporary data after processed
354
     * @return void
355
     */
356
    protected function cleanTempData(): void
357
    {
358
        $this->filesystem->directory($this->templateExtractDir)->delete();
359
        $this->filesystem->file($this->templateTempFile)->delete();
360
    }
361
}
362