Zipper::getMemoryLimit()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 7
nc 4
nop 0
dl 0
loc 11
rs 10
c 0
b 0
f 0
1
<?php
2
3
/** 
4
 * Copyright 2018 Social Manager.
5
 * PHP version 7.2.8
6
 *
7
 * It will Zip the file
8
 * 
9
 * @category Album_Manager
10
 * @package  Zipper
11
 * @author   Kishan Jasani <[email protected]>
12
 * @license  https://rtfbchallenge.tk/privacy_policy/privacy_policy.php 
13
 * @link     ""
14
 * 
15
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
16
 * use, copy, modify, and distribute this software in source code or binary
17
 * form for use in connection with the web services and APIs provided by
18
 * Kishan Jasani.
19
 *
20
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND
21
 */
22
$zip_folder = "";
23
/** 
24
 * Starting of zipping folders recursively 
25
 */
26
27
class Zipper
28
{
29
    /**
30
     * It will load the file which willl zip
31
     * 
32
     * @param String $source Source of the folder
33
     * 
34
     * @return $a
0 ignored issues
show
Documentation Bug introduced by
The doc comment $a at position 0 could not be parsed: Unknown type name '$a' at position 0 in $a.
Loading history...
35
     */
36
    public function loadZipFiles($source) 
37
    {
38
        if (!file_exists($source)) {
39
            return false;
40
        }
41
        $source = str_replace('\\', '/', realpath($source));
42
        $a = array();
43
        if (is_dir($source) === true) {
44
            $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);
45
            foreach ($files as $file) {
46
                $file = str_replace('\\', '/', $file);
47
                // Ignore "." and ".." folders
48
                if (in_array(substr($file, strrpos($file, '/') + 1), array('.', '..')))
49
                    continue;
50
                if (is_dir($file) === true) {
51
                    $a[] = array(
52
                    'type' => 'dir',
53
                    'source' => str_replace($source . '/', '', $file . '/'),
54
                    'file' => $file,
55
                    'size' => 0
56
                    );
57
                } else if (is_file($file) === true) {
58
                    $src = str_replace($source . '/', '', $file);
59
                    $size = filesize($file);
60
                    $a[] = array(
61
                    'type' => 'file',
62
                    'source' => $src,
63
                    'file' => $file,
64
                    'size' => false != $size ? $size : 16000 
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $size of type integer to the boolean false. If you are specifically checking for non-zero, consider using something more explicit like > 0 or !== 0 instead.
Loading history...
65
                    );
66
                }
67
            }
68
        }
69
        return $a;
70
    }
71
    /**
72
     * It will process the zip
73
     * 
74
     * @param String $foldercontent content of the folder
75
     * @param String $folder        folder name
76
     * @param String $maxsize       maximum size of the folder
77
     * 
78
     * @return array
79
     */
80
    public function processZip($foldercontent, $folder, $maxsize)
81
    {
82
        $split = array();
83
        $splits = 1;
84
        $t = 0;
85
        // Determine how many zip files to create
86
        if (isset($foldercontent)) {
87
            foreach ($foldercontent as $entry) {
0 ignored issues
show
Bug introduced by
The expression $foldercontent of type string is not traversable.
Loading history...
88
                $t = $t + $entry['size'];
89
                if ($entry['type'] == 'dir') {
90
                    $lastdir = $entry;
91
                }
92
                if ($t >= $maxsize) {
93
                    $splits++;
94
                    $t = 0;
95
                    // create lastdir in next archive, in case files still exist
96
                    // even if the next file is not in this archive it doesn't hurt
97
                    if ($lastdir !== '') {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $lastdir does not seem to be defined for all execution paths leading up to this point.
Loading history...
98
                        $split[$splits][] = $lastdir;
99
                    }
100
                }
101
                $split[$splits][] = $entry;
102
            }
103
            // delete the $foldercontent array
104
            unset($foldercontent);
105
            // Create the folder to put the zip files in
106
            $date = new DateTime();
107
            $tS = $date->format('YmdHis');
0 ignored issues
show
Unused Code introduced by
The assignment to $tS is dead and can be removed.
Loading history...
108
            // Process the splits
109
            foreach ($split as $idx => $sp) {
110
                // create the zip file
111
                $zip = new ZipArchive();
112
                $destination = $folder . '.zip';
113
                if (!$zip->open($destination, ZIPARCHIVE::CREATE)) {
114
                    return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type array.
Loading history...
115
                }
116
                $i = 1;
117
                $dir = "";
118
                foreach ($sp as $entry) {
119
                    if ($entry['type'] === 'dir') {
120
                        $dir = explode('\\', $entry['file']);
121
                        $zip->addEmptyDir(end($dir));
122
                    } else {
123
                        $zip->addFromString(
124
                            end($dir).'/'.$i.'.jpg', 
0 ignored issues
show
Bug introduced by
$dir of type string is incompatible with the type array expected by parameter $array of end(). ( Ignorable by Annotation )

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

124
                            end(/** @scrutinizer ignore-type */ $dir).'/'.$i.'.jpg', 
Loading history...
125
                            file_get_contents($entry['file'])
126
                        );
127
                        $i++;
128
                    }
129
                }
130
                $zip->close();
131
            }
132
            return array(
133
                'splits' => count($split),
134
                'foldername' => ''
135
            );
136
        }
137
    }
138
    /**
139
     * It will get the memory limit
140
     * 
141
     * @return "$memory_limit"
0 ignored issues
show
Documentation Bug introduced by
The doc comment "$memory_limit" at position 0 could not be parsed: Unknown type name '"$memory_limit"' at position 0 in "$memory_limit".
Loading history...
142
     */
143
    public function getMemoryLimit()
144
    {
145
        $memory_limit = ini_get('memory_limit');
146
        if (preg_match('/^(\d+)(.)$/', $memory_limit, $matches)) {
147
            if ($matches[2] == 'M') {
148
                $memory_limit = $matches[1] * 1024 * 1024; // nnnM -> nnn MB
149
            } else if ($matches[2] == 'K') {
150
                $memory_limit = $matches[1] * 1024; // nnnK -> nnn KB
151
            }
152
        }
153
        return $memory_limit;
154
    }
155
156
    /**
157
     * It will Make the zip
158
     * 
159
     * @param String $album_download_directory folder will be zip 
160
     * 
161
     * @return $zipfilename
0 ignored issues
show
Documentation Bug introduced by
The doc comment $zipfilename at position 0 could not be parsed: Unknown type name '$zipfilename' at position 0 in $zipfilename.
Loading history...
162
     */
163
    public function makeZip($album_download_directory) 
164
    {
165
        $zipfilename = "";
166
        if (isset($album_download_directory)) {
167
            //$zipfilename = 'libs/resources'.DIRECTORY_SEPARATOR.'albums'.DIRECTORY_SEPARATOR.'fb-album_'.date("Y-m-d").'_'.date("H-i-s");
168
            $zipfilename = 'public/fb-album_'.date("Y-m-d").'_'.date("H-i-s");
169
            
170
            $folder = dirname($_SERVER['PHP_SELF']).'/'.$album_download_directory;
171
            // Server Root
172
            $root = $_SERVER["DOCUMENT_ROOT"];
173
            // source of the folder to unpack
174
            $sourcedir = $root . $folder; // target directory
175
            // Don't use more than half the memory limit
176
            $memory_limit = $this->getMemoryLimit();
177
            $maxsize = $memory_limit / 2;
178
            // Is zipping possible on the server ?
179
            if (!extension_loaded('zip')) {
180
                echo 'Zipping not possible on this server';
181
                exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
182
            }
183
            // Get the files to zip
184
            $foldercontent = $this->loadZipFiles($sourcedir);
185
            if ($foldercontent === false) {
186
                echo 'Something went wrong gathering the file entries';
187
                exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
188
            }
189
            // Process the files to zip
190
            $zip = $this->processZip($foldercontent, $zipfilename, $maxsize);
0 ignored issues
show
Bug introduced by
$foldercontent of type array<mixed,array<string,integer|string|mixed>> is incompatible with the type string expected by parameter $foldercontent of Zipper::processZip(). ( Ignorable by Annotation )

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

190
            $zip = $this->processZip(/** @scrutinizer ignore-type */ $foldercontent, $zipfilename, $maxsize);
Loading history...
191
            if ($zip === false) {
0 ignored issues
show
introduced by
The condition $zip === false is always false.
Loading history...
192
                echo 'Something went wrong zipping the files';
193
            }    
194
            // clear the stat cache (created by filesize command)
195
            clearstatcache();
196
            include_once 'Unlink_Directory.php';
197
            $unlink_directory = new Unlink_Directory();
198
            $unlink_directory->removeDirectory($album_download_directory);
199
        }
200
        return $zipfilename;
201
    }
202
    /**
203
     * It will get the zip file
204
     * 
205
     * @param String $album_download_directory folder will be zip 
206
     * 
207
     * @return $response
0 ignored issues
show
Documentation Bug introduced by
The doc comment $response at position 0 could not be parsed: Unknown type name '$response' at position 0 in $response.
Loading history...
208
     */
209
    public function getZip($album_download_directory) 
210
    {
211
        $response = '<span style="color: #ffffff;">Sorry due to some reasons albums is not downloaded.</span>';
212
        if (isset($album_download_directory)) {
213
            $zip_folder = $this->makeZip($album_download_directory);
214
            if (!empty($zip_folder)) {
215
                $response = $zip_folder;
216
            }
217
        }
218
        return $response;
219
    }
220
}
221
?>
0 ignored issues
show
Best Practice introduced by
It is not recommended to use PHP's closing tag ?> in files other than templates.

Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.

A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.

Loading history...