Issues (1)

src/Archive/Zip.php (1 issue)

Labels
Severity
1
<?php
2
3
/**
4
 * Platine Docx template
5
 *
6
 * Platine Docx template is the lightweight library to manipulate the content of .docx files
7
 *
8
 * This content is released under the MIT License (MIT)
9
 *
10
 * Copyright (c) 2020 Platine Docx template
11
 *
12
 * Permission is hereby granted, free of charge, to any person obtaining a copy
13
 * of this software and associated documentation files (the "Software"), to deal
14
 * in the Software without restriction, including without limitation the rights
15
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16
 * copies of the Software, and to permit persons to whom the Software is
17
 * furnished to do so, subject to the following conditions:
18
 *
19
 * The above copyright notice and this permission notice shall be included in all
20
 * copies or substantial portions of the Software.
21
 *
22
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28
 * SOFTWARE.
29
 */
30
31
/**
32
 *  @file Zip.php
33
 *
34
 *  The Zip Archive manipulation class
35
 *
36
 *  @package    Platine\DocxTemplate\Archive
37
 *  @author Platine Developers Team
38
 *  @copyright  Copyright (c) 2020
39
 *  @license    http://opensource.org/licenses/MIT  MIT License
40
 *  @link   https://www.platine-php.com
41
 *  @version 1.0.0
42
 *  @filesource
43
 */
44
45
declare(strict_types=1);
46
47
namespace Platine\DocxTemplate\Archive;
48
49
use FilesystemIterator;
50
use Platine\DocxTemplate\DocxExtractorInterface;
51
use Platine\DocxTemplate\Exception\DocxArchiveException;
52
use RecursiveDirectoryIterator;
53
use RecursiveIteratorIterator;
54
use ZipArchive;
55
56
/**
57
 * @class Zip
58
 * @package Platine\DocxTemplate\Archive
59
 */
60
class Zip implements DocxExtractorInterface
61
{
62
    /**
63
     * The zip archive instance
64
     * @var ZipArchive
65
     */
66
    protected ZipArchive $zip;
67
68
    /**
69
     * Create new instance
70
     * @param ZipArchive|null $zip
71
     */
72
    public function __construct(?ZipArchive $zip = null)
73
    {
74
        $this->zip = $zip ?? new ZipArchive();
75
    }
76
77
    /**
78
     * {@inheritdoc}
79
     */
80
    public function archiveFolder(string $folder, string $filename): void
81
    {
82
        $create = $this->zip->open(
83
            $filename,
84
            ZipArchive::CREATE | ZipArchive::OVERWRITE
85
        );
86
        if ($create === true) {
87
             // Create recursive directory iterator
88
            $files = new RecursiveIteratorIterator(
89
                new RecursiveDirectoryIterator(
90
                    $folder,
91
                    FilesystemIterator::SKIP_DOTS
92
                ),
93
                RecursiveIteratorIterator::LEAVES_ONLY
94
            );
95
96
            foreach ($files as $name => $file) {
97
                //NOTE: Always use "/" as separator
98
                $name = str_replace(
99
                    ['/', '\\'],
100
                    '/',
101
                    substr($name, strlen($folder . '/'))
0 ignored issues
show
It seems like $name can also be of type null and true; however, parameter $string of substr() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

101
                    substr(/** @scrutinizer ignore-type */ $name, strlen($folder . '/'))
Loading history...
102
                );
103
                $this->zip->addFile($file->getRealPath(), $name);
104
            }
105
            $this->zip->close();
106
        } else {
107
            throw new DocxArchiveException(sprintf(
108
                'Can not open file [%s], error code [%s]',
109
                $filename,
110
                $create
111
            ));
112
        }
113
    }
114
115
    /**
116
     * {@inheritdoc}
117
     */
118
    public function extract(string $archive, string $destination = '.'): void
119
    {
120
        $open = $this->zip->open($archive);
121
        if ($open !== true) {
122
            throw new DocxArchiveException(sprintf(
123
                'Can not open file [%s], error code [%s]',
124
                $archive,
125
                $open
126
            ));
127
        }
128
129
        if (!$this->zip->extractTo($destination)) {
130
            throw new DocxArchiveException(sprintf(
131
                'Can not extract file [%s]',
132
                $archive
133
            ));
134
        }
135
    }
136
137
    /**
138
     * {@inheritdoc}
139
     */
140
    public function totalFiles(): int
141
    {
142
        return $this->zip->count();
143
    }
144
145
    /**
146
     * {@inheritdoc}
147
     */
148
    public function close(): void
149
    {
150
        $this->zip->close();
151
    }
152
153
    /**
154
     * {@inheritdoc}
155
     */
156
    public function getInfo(int $index): ArchiveInfo
157
    {
158
        $stat = $this->zip->statIndex($index);
159
        if ($stat === false) {
160
            throw new DocxArchiveException(sprintf(
161
                'Can not stat the archive file at index [%d]',
162
                $index
163
            ));
164
        }
165
166
        return new ArchiveInfo(
167
            $stat['name'],
168
            $stat['index'],
169
            $stat['size'],
170
            $stat['mtime'],
171
            $stat['crc']
172
        );
173
    }
174
}
175