ZipFile   A
last analyzed

Complexity

Total Complexity 15

Size/Duplication

Total Lines 162
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 43
dl 0
loc 162
rs 10
c 0
b 0
f 0
wmc 15

7 Methods

Rating   Name   Duplication   Size   Complexity  
A getFilesCount() 0 13 2
A setFileName() 0 5 1
A getSize() 0 9 2
A getSha1() 0 9 2
A getContent() 0 28 6
A getFileName() 0 3 1
A __construct() 0 4 1
1
<?php
2
3
/**
4
 * Copyright (c) 2018 Francois-Xavier Soubirou.
5
 *
6
 * This file is part of ci-report.
7
 *
8
 * ci-report is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * ci-report is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with ci-report. If not, see <http://www.gnu.org/licenses/>.
20
 */
21
declare(strict_types=1);
22
23
namespace App\Entity;
24
25
use JMS\Serializer\Annotation as Serializer;
26
use Symfony\Component\Filesystem\Exception\FileNotFoundException;
27
use ZipArchive;
28
29
/**
30
 * Zip file class.
31
 *
32
 * @category  ci-report app
33
 *
34
 * @author    Francois-Xavier Soubirou <[email protected]>
35
 * @copyright 201 Francois-Xavier Soubirou
36
 * @license   http://www.gnu.org/licenses/   GPLv3
37
 *
38
 * @see      https://www.ci-report.io
39
 */
40
class ZipFile
41
{
42
    /**
43
     * @var string
44
     *
45
     * @Serializer\Exclude
46
     */
47
    private $targetDir;
48
49
    /**
50
     * @var string
51
     *
52
     * @Serializer\Exclude
53
     */
54
    private $fileName;
55
56
    const MAX_FILES = 2000;
57
58
    /**
59
     * Constructor.
60
     *
61
     * @param string $targetDir Directory of file
62
     * @param string $fileName  Name of zip file
63
     */
64
    public function __construct(string $targetDir, string $fileName)
65
    {
66
        $this->targetDir = $targetDir;
67
        $this->fileName = $fileName;
68
    }
69
70
    /**
71
     * Set file name.
72
     *
73
     * @param string $name Name
74
     *
75
     * @return ZipFile
76
     */
77
    public function setFileName(string $name): self
78
    {
79
        $this->fileName = $name;
80
81
        return $this;
82
    }
83
84
    /**
85
     * Get file name.
86
     *
87
     * @return string
88
     */
89
    public function getFileName(): string
90
    {
91
        return $this->fileName;
92
    }
93
94
    /**
95
     * Sha1 hash of zip file.
96
     *
97
     * @return string
98
     *
99
     * @throws FileNotFoundException
100
     *
101
     * @Serializer\VirtualProperty
102
     * @Serializer\SerializedName("sha1")
103
     * @Serializer\Type("string")
104
     * @Serializer\Groups({"public", "private"})
105
     */
106
    public function getSha1(): string
107
    {
108
        $fileNameWithPath = $this->targetDir.'/'.$this->fileName;
109
110
        if (!file_exists($fileNameWithPath)) {
111
            throw new FileNotFoundException();
112
        }
113
114
        return sha1_file($fileNameWithPath);
115
    }
116
117
    /**
118
     * File size in bytes.
119
     *
120
     * @return int
121
     *
122
     * @throws FileNotFoundException
123
     *
124
     * @Serializer\VirtualProperty
125
     * @Serializer\SerializedName("size")
126
     * @Serializer\Type("int")
127
     * @Serializer\Groups({"public", "private"})
128
     */
129
    public function getSize(): int
130
    {
131
        $fileNameWithPath = $this->targetDir.'/'.$this->fileName;
132
133
        if (!file_exists($fileNameWithPath)) {
134
            throw new FileNotFoundException();
135
        }
136
137
        return filesize($fileNameWithPath);
138
    }
139
140
    /**
141
     * Files and directories count in zip file.
142
     *
143
     * @return int
144
     *
145
     * @throws FileNotFoundException
146
     *
147
     * @Serializer\VirtualProperty
148
     * @Serializer\SerializedName("count")
149
     * @Serializer\Type("int")
150
     * @Serializer\Groups({"public", "private"})
151
     */
152
    public function getFilesCount(): int
153
    {
154
        $fileNameWithPath = $this->targetDir.'/'.$this->fileName;
155
156
        if (!file_exists($fileNameWithPath)) {
157
            throw new FileNotFoundException();
158
        }
159
        $za = new ZipArchive();
160
        $za->open($fileNameWithPath);
161
        $count = $za->numFiles;
162
        $za->close();
163
164
        return $count;
165
    }
166
167
    /**
168
     * Get content in array of files and directories.
169
     *
170
     * @return array
171
     *
172
     * @throws FileNotFoundException
173
     */
174
    public function getContent(): array
175
    {
176
        $fileNameWithPath = $this->targetDir.'/'.$this->fileName;
177
178
        if (!file_exists($fileNameWithPath)) {
179
            throw new FileNotFoundException();
180
        }
181
        $za = new ZipArchive();
182
        $za->open($fileNameWithPath);
183
        $limit = min($za->numFiles, self::MAX_FILES);
184
185
        $directories = array();
186
        $files = array();
187
188
        for ($i = 0; $i < $limit; ++$i) {
189
            $stat = $za->statIndex($i);
190
            $first = strtok($stat['name'], '/');
191
            if (($first === $stat['name']) && ($stat['crc'] > 0)) {
192
                $files[$stat['name']] = $stat['size'];
193
            } else {
194
                if (!in_array($first, $directories)) {
195
                    $directories[] = $first;
196
                }
197
            }
198
        }
199
        $za->close();
200
201
        return array('directories' => $directories, 'files' => $files);
202
    }
203
}
204