1: <?php
2:
3: /*
4: * The MIT License
5: *
6: * Copyright 2014 Damien Doussaud (namide.com).
7: *
8: * Permission is hereby granted, free of charge, to any person obtaining a copy
9: * of this software and associated documentation files (the "Software"), to deal
10: * in the Software without restriction, including without limitation the rights
11: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12: * copies of the Software, and to permit persons to whom the Software is
13: * furnished to do so, subject to the following conditions:
14: *
15: * The above copyright notice and this permission notice shall be included in
16: * all copies or substantial portions of the Software.
17: *
18: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21: * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24: * THE SOFTWARE.
25: */
26:
27: namespace Flea;
28:
29: /**
30: * Utils to write directories or files
31: *
32: * @author Namide
33: */
34: class FileUtil {
35:
36: /**
37: * Writes the content in a file.
38: * If the directory doesn't exist, it's automatically created.
39: *
40: * @param string &$content Content of the file
41: * @param string $fileName Name of the file
42: */
43: public static function writeFile(&$content, $fileName) {
44: self::writeDirOfFile($fileName);
45: file_put_contents($fileName, $content, LOCK_EX);
46: }
47:
48: /**
49: * Writes recursively the directories of a files if it doesn't exist
50: *
51: * @param string $fileName Name of the file
52: */
53: public static function writeDirOfFile($fileName) {
54: $dir = explode('/', $fileName);
55: array_pop($dir);
56: self::writeDir(implode($dir, '/'));
57: }
58:
59: /**
60: * Writes a directory if it doesn't exist.
61: * It works recursively.
62: *
63: * @param string $dirName Directory to write
64: */
65: public static function writeDir($dirName) {
66: $path = explode('/', $dirName);
67:
68: $dirName = '';
69: while (count($path) > 0) {
70: $dirName .= $path[0] . '/';
71: if (!file_exists($dirName)) {
72: mkdir($dirName, 0777);
73: }
74: array_shift($path);
75: }
76: }
77:
78: /**
79: * Return the content of your CSS file with absolute URL for your pictures
80: *
81: * @param string $cssFile Path of your CSS file
82: * @return string Content of your CSS
83: */
84: public static function getCssContentWithAbsUrl($cssFile) {
85: $content = file_get_contents($cssFile);
86: $regex = '/url\(([\'"]?.[^\'"]*\.(png|jpg|jpeg|gif)[\'"]?)\)/i';
87: preg_match_all($regex, $content, $links);
88: for ($i = 0; $i < count($links[1]); $i++) {
89: $newUrlCss = self::getAbsPathFromFile($cssFile, $links[1][$i]);
90: $content = str_replace($links[1][$i], $newUrlCss, $content);
91: }
92: return $content;
93: }
94:
95: /**
96: * Use $rootPath to create an absolute URL for $relPath.
97: * Can be use to change an URL in a CSS file.
98: *
99: * @param string $rootPath Absolute URL of the container file like "http://domain.com/css/style.css"
100: * @param string $relPath Relative URL of the file like "../img/picture.jpg"
101: * @return string Absolute URL of the file like "http://domain.com/img/picture.jpg"
102: */
103: public static function getAbsPathFromFile($rootPath, $relPath) {
104: $root = explode('/', $rootPath);
105: $rel = explode('/', $relPath);
106:
107: //if ( is_file($rootPath) )
108: array_pop($root);
109:
110: while ($rel[0] == '..') {
111: array_pop($root);
112: array_shift($rel);
113: }
114: $final = array_merge($root, $rel);
115:
116: return implode('/', $final);
117: }
118:
119: /**
120: * Writes a directory with .htaccess (deny from all) if it doesn't exist.
121: * It works recursively.
122: *
123: * @param string $dirName Directory of the .htaccess
124: */
125: public static function writeProtectedDir($dirName) {
126: FileUtil::writeDir($dirName);
127:
128: if (!file_exists($dirName . '.htaccess')) {
129: $htaccess = fopen($dirName . '.htaccess', "w");
130: $htaccessContent = 'deny from all';
131: fwrite($htaccess, $htaccessContent);
132: fclose($htaccess);
133: }
134: }
135:
136: /**
137: * Size of the directory in octets
138: *
139: * @param string $dir Directory to mesure
140: * @return float Size of the directory in octet
141: */
142: public static function getDirSize($dirName) {
143: $size = 0;
144: foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dirName)) as $file) {
145: $size += $file->getSize();
146: }
147: return $size;
148: }
149:
150: /**
151: * Size of the directory in string with type (bytes, kilo-bytes...)
152: *
153: * @param string $dirName Directory to mesure
154: * @param int $round Number to float
155: * @return string Formated size of the directory
156: */
157: public static function getFormatedSize($dirName, $round = 2) {
158: $size = self::getDirSize($dirName);
159:
160: //Size must be bytes!
161: $sizes = array('B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
162: for ($i = 0; $size > 1024 && $i < count($sizes) - 1; $i++)
163: $size /= 1024;
164:
165: return round($size, $round) . ' ' . $sizes[$i];
166: }
167:
168: /**
169: * Delete a directory and his content
170: *
171: * @param string $dirName Directory to delete
172: * @return int true on success or false on failure
173: */
174: public static function delDirRecursively($dirName) {
175: if (!file_exists($dirName)) {
176: return 0;
177: }
178:
179: $files = array_diff(scandir($dirName), array('.', '..'));
180: foreach ($files as $file) {
181: if (is_dir($dirName . '/' . $file)) {
182: self::delDirRecursively($dirName . '/' . $file);
183: } else {
184: unlink($dirName . '/' . $file);
185: }
186: }
187:
188: return rmdir($dirName);
189: }
190:
191: /**
192: * Delete file
193: *
194: * @param type $file Path of file to delete
195: * @param type $recursEmptyDir Delete containers directories empty
196: * @return boolean File successfull deleted
197: */
198: public static function delFile($file, $recursEmptyDir = false) {
199: if (!file_exists($file)) {
200: return false;
201: }
202: unlink($file);
203:
204: if ($recursEmptyDir) {
205: $dir = $file;
206: do {
207: $dir = explode('/', $dir);
208: if (count($dir) < 1)
209: return true;
210: array_pop($dir);
211: $dir = implode('/', $dir);
212: self::delEmptyDirRecursively($dir);
213: }
214: while (self::isEmpty($dir));
215: }
216:
217: return true;
218: }
219:
220: /**
221: * Is the directory empty
222: *
223: * @param type $dir Directtory to test
224: * @return int Is deleted
225: */
226: public static function isEmpty($dir) {
227: if (!file_exists($dir)) {
228: return false;
229: }
230: if (is_file($dir)) {
231: return true;
232: }
233:
234: $files = array_diff(scandir($dir), array('.', '..', '.DS_Store', 'Thumbs.db'));
235: return count($files) < 1;
236: }
237:
238: /**
239: * Delete all files and directories and return the number of file deleted
240: *
241: * @param string $dirName Directory to delete
242: * @return int Number of files deleted (without directories)
243: */
244: public static function delEmptyDirRecursively($dirName) {
245: $numChilds = 0;
246:
247: if (!file_exists($dirName)) {
248: return 0;
249: }
250: if (is_file($dirName)) {
251: return 1;
252: }
253:
254: $files = array_diff(scandir($dirName), array('.', '..', '.DS_Store', 'Thumbs.db'));
255: foreach ($files as $file) {
256: if (is_dir($dirName . '/' . $file)) {
257: $numChilds += self::delEmptyDirRecursively($dirName . '/' . $file);
258: } else {
259: $numChilds++;
260: }
261: }
262:
263: if ($numChilds < 1) {
264: rmdir($dirName);
265: }
266:
267: return $numChilds;
268: }
269:
270: /**
271: * Copy the recursivly the directory ($dir2copy) to the directory ($dir2paste)
272: *
273: * @param string $dir2copy Original directory
274: * @param string $dir2paste New directory
275: */
276: public static function copyDir($dir2copy, $dir2paste) {
277: if (is_dir($dir2copy)) {
278: if ($dh = opendir($dir2copy)) {
279: while (($file = readdir($dh)) !== false) {
280: if (!is_dir($dir2paste)) {
281: mkdir($dir2paste, 0777);
282: }
283:
284: if (is_dir($dir2copy . $file) && $file != '..' && $file != '.') {
285: $this->copyDir($dir2copy . $file . '/', $dir2paste . $file . '/');
286: } elseif ($file != '..' &&
287: $file != '.') {
288: copy($dir2copy . $file, $dir2paste . $file);
289: }
290: }
291:
292: closedir($dh);
293: }
294: }
295: }
296:
297: /**
298: * Copy the directory ($dir2copy) to the directory ($dir2paste) for type.
299: * Ex for copy without php:
300: * copyDirWithoutType( 'original/dir', 'new/dir', array('php', 'php4', 'php5') );
301: *
302: * @param string $dir2copy Original directory
303: * @param string $dir2paste New directory
304: * @param array $extentions Exceptions list
305: */
306: public static function copyDirWithoutType($dir2copy, $dir2paste, array $extentions = null) {
307: if ($extentions === null) {
308: $extentions = array();
309: }
310:
311: if (is_dir($dir2copy)) {
312:
313: if ($dh = opendir($dir2copy)) {
314: while (($file = readdir($dh)) !== false) {
315: if (!is_dir($dir2paste)) {
316: mkdir($dir2paste, 0777);
317: }
318:
319: if (is_dir($dir2copy . $file) && $file != '..' && $file != '.') {
320: self::copyDirWithoutPhpFiles($dir2copy . $file . '/', $dir2paste . $file . '/');
321: } elseif ($file != '..' &&
322: $file != '.') {
323: $ok = true;
324: foreach ($extentions as $ext) {
325: $l = count($ext);
326:
327: if (strtolower(substr(strrchr($file, '.'), 1)) === $ext) {
328: $ok = false;
329: }
330: }
331: if ($ok) {
332: copy($dir2copy . $file, $dir2paste . $file);
333: }
334: }
335: }
336:
337: closedir($dh);
338: }
339: }
340: }
341:
342: }
343: