diff --git a/.gitignore b/.gitignore index 1258669..9bea433 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ - -.DS_Store + +.DS_Store diff --git a/LICENSE b/LICENSE index aaefb5a..cd5ace5 100644 --- a/LICENSE +++ b/LICENSE @@ -1,21 +1,21 @@ -MIT License - -Copyright (c) 2016 Steeve Andrian Salim - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +MIT License + +Copyright (c) 2016 Steeve Andrian Salim + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/composer.json b/composer.json index 4065578..4a91203 100644 --- a/composer.json +++ b/composer.json @@ -1,42 +1,42 @@ -{ - "name": "o2system/filesystem", - "description": "PHP Filesystem Library", - "license": "MIT", - "type": "package", - "keywords": [ - "utilities", - "php", - "framework", - "driver", - "libraries" - ], - "authors": [ - { - "name": "Steeven Andrian Salim", - "email": "steevenz@steevenz.com", - "homepage": "http://www.steevenz.com", - "role": "Founder and Lead Project" - }, - { - "name": "Teguh Rianto", - "email": "teguh.rianto22@gmail.com", - "homepage": "http://teguhrianto22.pusku.com", - "role": "Template Designer" - } - ], - "support": { - "email": "o2system@yahoo.com", - "issues": "https://github.com/o2system/filesystem/issues", - "forum": "https://www.facebook.com/groups/498147006994512" - }, - "require": { - "php": "^7.2.0", - "ext-fileinfo": "*", - "o2system/kernel": "*" - }, - "autoload": { - "psr-4": { - "O2System\\Filesystem\\": "src" - } - } -} +{ + "name": "o2system/filesystem", + "description": "PHP Filesystem Library", + "license": "MIT", + "type": "package", + "keywords": [ + "utilities", + "php", + "framework", + "driver", + "libraries" + ], + "authors": [ + { + "name": "Steeven Andrian Salim", + "email": "steevenz@steevenz.com", + "homepage": "http://www.steevenz.com", + "role": "Founder and Lead Project" + }, + { + "name": "Teguh Rianto", + "email": "teguh.rianto22@gmail.com", + "homepage": "http://teguhrianto22.pusku.com", + "role": "Template Designer" + } + ], + "support": { + "email": "o2system@yahoo.com", + "issues": "https://github.com/o2system/filesystem/issues", + "forum": "https://www.facebook.com/groups/498147006994512" + }, + "require": { + "php": "^7.2.0", + "ext-fileinfo": "*", + "o2system/kernel": "*" + }, + "autoload": { + "psr-4": { + "O2System\\Filesystem\\": "src" + } + } +} diff --git a/src/Config/Mimes.php b/src/Config/Mimes.php index bb4cabc..acba335 100644 --- a/src/Config/Mimes.php +++ b/src/Config/Mimes.php @@ -1,279 +1,279 @@ - [ - 'application/mac-binhex40', - 'application/mac-binhex', - 'application/x-binhex40', - 'application/x-mac-binhex40', - ], - 'cpt' => 'application/mac-compactpro', - 'csv' => [ - 'text/x-comma-separated-values', - 'text/comma-separated-values', - 'application/octet-stream', - 'application/vnd.ms-excel', - 'application/x-csv', - 'text/x-csv', - 'text/csv', - 'application/csv', - 'application/excel', - 'application/vnd.msexcel', - 'text/plain', - ], - 'bin' => [ - 'application/macbinary', - 'application/mac-binary', - 'application/octet-stream', - 'application/x-binary', - 'application/x-macbinary', - ], - 'dms' => 'application/octet-stream', - 'lha' => 'application/octet-stream', - 'lzh' => 'application/octet-stream', - 'exe' => ['application/octet-stream', 'application/x-msdownload'], - 'class' => 'application/octet-stream', - 'psd' => ['application/x-photoshop', 'image/vnd.adobe.photoshop'], - 'so' => 'application/octet-stream', - 'sea' => 'application/octet-stream', - 'dll' => 'application/octet-stream', - 'oda' => 'application/oda', - 'pdf' => [ - 'application/pdf', - 'application/force-download', - 'application/x-download', - 'binary/octet-stream', - ], - 'ai' => ['application/pdf', 'application/postscript'], - 'eps' => 'application/postscript', - 'ps' => 'application/postscript', - 'smi' => 'application/smil', - 'smil' => 'application/smil', - 'mif' => 'application/vnd.mif', - 'xls' => [ - 'application/vnd.ms-excel', - 'application/msexcel', - 'application/x-msexcel', - 'application/x-ms-excel', - 'application/x-excel', - 'application/x-dos_ms_excel', - 'application/xls', - 'application/x-xls', - 'application/excel', - 'application/download', - 'application/vnd.ms-office', - 'application/msword', - ], - 'ppt' => [ - 'application/powerpoint', - 'application/vnd.ms-powerpoint', - 'application/vnd.ms-office', - 'application/msword', - ], - 'pptx' => [ - 'application/vnd.openxmlformats-officedocument.presentationml.presentation', - 'application/x-zip', - 'application/zip', - ], - 'wbxml' => 'application/wbxml', - 'wmlc' => 'application/wmlc', - 'dcr' => 'application/x-director', - 'dir' => 'application/x-director', - 'dxr' => 'application/x-director', - 'dvi' => 'application/x-dvi', - 'gtar' => 'application/x-gtar', - 'gz' => 'application/x-gzip', - 'gzip' => 'application/x-gzip', - 'php' => [ - 'application/x-httpd-php', - 'application/php', - 'application/x-php', - 'text/php', - 'text/x-php', - 'application/x-httpd-php-source', - ], - 'php4' => 'application/x-httpd-php', - 'php3' => 'application/x-httpd-php', - 'phtml' => 'application/x-httpd-php', - 'phps' => 'application/x-httpd-php-source', - 'js' => ['application/x-javascript', 'text/plain'], - 'swf' => 'application/x-shockwave-flash', - 'sit' => 'application/x-stuffit', - 'tar' => 'application/x-tar', - 'tgz' => ['application/x-tar', 'application/x-gzip-compressed'], - 'z' => 'application/x-compress', - 'xhtml' => 'application/xhtml+xml', - 'xht' => 'application/xhtml+xml', - 'zip' => [ - 'application/x-zip', - 'application/zip', - 'application/x-zip-compressed', - 'application/s-compressed', - 'multipart/x-zip', - ], - 'rar' => ['application/x-rar', 'application/rar', 'application/x-rar-compressed'], - 'mid' => 'audio/midi', - 'midi' => 'audio/midi', - 'mpga' => 'audio/mpeg', - 'mp2' => 'audio/mpeg', - 'mp3' => ['audio/mpeg', 'audio/mpg', 'audio/mpeg3', 'audio/mp3'], - 'aif' => ['audio/x-aiff', 'audio/aiff'], - 'aiff' => ['audio/x-aiff', 'audio/aiff'], - 'aifc' => 'audio/x-aiff', - 'ram' => 'audio/x-pn-realaudio', - 'rm' => 'audio/x-pn-realaudio', - 'rpm' => 'audio/x-pn-realaudio-plugin', - 'ra' => 'audio/x-realaudio', - 'rv' => 'video/vnd.rn-realvideo', - 'wav' => ['audio/x-wav', 'audio/wave', 'audio/wav'], - 'bmp' => [ - 'image/bmp', - 'image/x-bmp', - 'image/x-bitmap', - 'image/x-xbitmap', - 'image/x-win-bitmap', - 'image/x-windows-bmp', - 'image/ms-bmp', - 'image/x-ms-bmp', - 'application/bmp', - 'application/x-bmp', - 'application/x-win-bitmap', - ], - 'gif' => 'image/gif', - 'jpeg' => 'image/jpeg', - 'jpg' => 'image/jpeg', - 'jpe' => 'image/jpeg', - 'png' => ['image/png', 'image/x-png'], - 'tiff' => 'image/tiff', - 'tif' => 'image/tiff', - 'css' => ['text/css', 'text/plain'], - 'html' => ['text/html', 'text/plain'], - 'htm' => ['text/html', 'text/plain'], - 'shtml' => ['text/html', 'text/plain'], - 'txt' => 'text/plain', - 'text' => 'text/plain', - 'log' => ['text/plain', 'text/x-log'], - 'rtx' => 'text/richtext', - 'rtf' => 'text/rtf', - 'xml' => ['application/xml', 'text/xml', 'text/plain'], - 'xsl' => ['application/xml', 'text/xsl', 'text/xml'], - 'mpeg' => 'video/mpeg', - 'mpg' => 'video/mpeg', - 'mpe' => 'video/mpeg', - 'qt' => 'video/quicktime', - 'mov' => 'video/quicktime', - 'avi' => ['video/x-msvideo', 'video/msvideo', 'video/avi', 'application/x-troff-msvideo'], - 'movie' => 'video/x-sgi-movie', - 'doc' => ['application/msword', 'application/vnd.ms-office'], - 'docx' => [ - 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', - 'application/zip', - 'application/msword', - 'application/x-zip', - ], - 'dot' => ['application/msword', 'application/vnd.ms-office'], - 'dotx' => [ - 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', - 'application/zip', - 'application/msword', - ], - 'xlsx' => [ - 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', - 'application/zip', - 'application/vnd.ms-excel', - 'application/msword', - 'application/x-zip', - ], - 'word' => ['application/msword', 'application/octet-stream'], - 'xl' => 'application/excel', - 'eml' => 'message/rfc822', - 'json' => ['application/json', 'text/json'], - 'pem' => ['application/x-x509-user-cert', 'application/x-pem-file', 'application/octet-stream'], - 'p10' => ['application/x-pkcs10', 'application/pkcs10'], - 'p12' => 'application/x-pkcs12', - 'p7a' => 'application/x-pkcs7-signature', - 'p7c' => ['application/pkcs7-mime', 'application/x-pkcs7-mime'], - 'p7m' => ['application/pkcs7-mime', 'application/x-pkcs7-mime'], - 'p7r' => 'application/x-pkcs7-certreqresp', - 'p7s' => 'application/pkcs7-signature', - 'crt' => ['application/x-x509-ca-cert', 'application/x-x509-user-cert', 'application/pkix-cert'], - 'crl' => ['application/pkix-crl', 'application/pkcs-crl'], - 'der' => 'application/x-x509-ca-cert', - 'kdb' => 'application/octet-stream', - 'pgp' => 'application/pgp', - 'gpg' => 'application/gpg-keys', - 'sst' => 'application/octet-stream', - 'csr' => 'application/octet-stream', - 'rsa' => 'application/x-pkcs7', - 'cer' => ['application/pkix-cert', 'application/x-x509-ca-cert'], - '3g2' => 'video/3gpp2', - '3gp' => 'video/3gp', - 'mp4' => 'video/mp4', - 'm4a' => 'audio/x-m4a', - 'f4v' => 'video/mp4', - 'webm' => 'video/webm', - 'aac' => 'audio/x-acc', - 'm4u' => 'application/vnd.mpegurl', - 'm3u' => 'text/plain', - 'xspf' => 'application/xspf+xml', - 'vlc' => 'application/videolan', - 'wmv' => ['video/x-ms-wmv', 'video/x-ms-asf'], - 'au' => 'audio/x-au', - 'ac3' => 'audio/ac3', - 'flac' => 'audio/x-flac', - 'ogg' => 'audio/ogg', - 'kmz' => ['application/vnd.google-earth.kmz', 'application/zip', 'application/x-zip'], - 'kml' => ['application/vnd.google-earth.kml+xml', 'application/xml', 'text/xml'], - 'ics' => 'text/calendar', - 'ical' => 'text/calendar', - 'zsh' => 'text/x-scriptzsh', - '7zip' => [ - 'application/x-compressed', - 'application/x-zip-compressed', - 'application/zip', - 'multipart/x-zip', - ], - 'cdr' => [ - 'application/cdr', - 'application/coreldraw', - 'application/x-cdr', - 'application/x-coreldraw', - 'image/cdr', - 'image/x-cdr', - 'zz-application/zz-winassoc-cdr', - ], - 'wma' => ['audio/x-ms-wma', 'video/x-ms-asf'], - 'jar' => [ - 'application/java-archive', - 'application/x-java-application', - 'application/x-jar', - 'application/x-compressed', - ], - 'svg' => ['image/svg+xml', 'application/xml', 'text/xml'], - 'vcf' => 'text/x-vcard', - 'ttf' => ['application/x-font-ttf', 'application/x-font-truetype'], - 'otf' => 'application/x-font-opentype', - 'woff' => 'application/font-woff', - 'woff2' => 'application/font-woff2', - 'eot' => 'application/vnd.ms-fontobject', - 'sfnt' => 'application/font-sfnt', - 'ico' => 'image/x-icon', + [ + 'application/mac-binhex40', + 'application/mac-binhex', + 'application/x-binhex40', + 'application/x-mac-binhex40', + ], + 'cpt' => 'application/mac-compactpro', + 'csv' => [ + 'text/x-comma-separated-values', + 'text/comma-separated-values', + 'application/octet-stream', + 'application/vnd.ms-excel', + 'application/x-csv', + 'text/x-csv', + 'text/csv', + 'application/csv', + 'application/excel', + 'application/vnd.msexcel', + 'text/plain', + ], + 'bin' => [ + 'application/macbinary', + 'application/mac-binary', + 'application/octet-stream', + 'application/x-binary', + 'application/x-macbinary', + ], + 'dms' => 'application/octet-stream', + 'lha' => 'application/octet-stream', + 'lzh' => 'application/octet-stream', + 'exe' => ['application/octet-stream', 'application/x-msdownload'], + 'class' => 'application/octet-stream', + 'psd' => ['application/x-photoshop', 'image/vnd.adobe.photoshop'], + 'so' => 'application/octet-stream', + 'sea' => 'application/octet-stream', + 'dll' => 'application/octet-stream', + 'oda' => 'application/oda', + 'pdf' => [ + 'application/pdf', + 'application/force-download', + 'application/x-download', + 'binary/octet-stream', + ], + 'ai' => ['application/pdf', 'application/postscript'], + 'eps' => 'application/postscript', + 'ps' => 'application/postscript', + 'smi' => 'application/smil', + 'smil' => 'application/smil', + 'mif' => 'application/vnd.mif', + 'xls' => [ + 'application/vnd.ms-excel', + 'application/msexcel', + 'application/x-msexcel', + 'application/x-ms-excel', + 'application/x-excel', + 'application/x-dos_ms_excel', + 'application/xls', + 'application/x-xls', + 'application/excel', + 'application/download', + 'application/vnd.ms-office', + 'application/msword', + ], + 'ppt' => [ + 'application/powerpoint', + 'application/vnd.ms-powerpoint', + 'application/vnd.ms-office', + 'application/msword', + ], + 'pptx' => [ + 'application/vnd.openxmlformats-officedocument.presentationml.presentation', + 'application/x-zip', + 'application/zip', + ], + 'wbxml' => 'application/wbxml', + 'wmlc' => 'application/wmlc', + 'dcr' => 'application/x-director', + 'dir' => 'application/x-director', + 'dxr' => 'application/x-director', + 'dvi' => 'application/x-dvi', + 'gtar' => 'application/x-gtar', + 'gz' => 'application/x-gzip', + 'gzip' => 'application/x-gzip', + 'php' => [ + 'application/x-httpd-php', + 'application/php', + 'application/x-php', + 'text/php', + 'text/x-php', + 'application/x-httpd-php-source', + ], + 'php4' => 'application/x-httpd-php', + 'php3' => 'application/x-httpd-php', + 'phtml' => 'application/x-httpd-php', + 'phps' => 'application/x-httpd-php-source', + 'js' => ['application/x-javascript', 'text/plain'], + 'swf' => 'application/x-shockwave-flash', + 'sit' => 'application/x-stuffit', + 'tar' => 'application/x-tar', + 'tgz' => ['application/x-tar', 'application/x-gzip-compressed'], + 'z' => 'application/x-compress', + 'xhtml' => 'application/xhtml+xml', + 'xht' => 'application/xhtml+xml', + 'zip' => [ + 'application/x-zip', + 'application/zip', + 'application/x-zip-compressed', + 'application/s-compressed', + 'multipart/x-zip', + ], + 'rar' => ['application/x-rar', 'application/rar', 'application/x-rar-compressed'], + 'mid' => 'audio/midi', + 'midi' => 'audio/midi', + 'mpga' => 'audio/mpeg', + 'mp2' => 'audio/mpeg', + 'mp3' => ['audio/mpeg', 'audio/mpg', 'audio/mpeg3', 'audio/mp3'], + 'aif' => ['audio/x-aiff', 'audio/aiff'], + 'aiff' => ['audio/x-aiff', 'audio/aiff'], + 'aifc' => 'audio/x-aiff', + 'ram' => 'audio/x-pn-realaudio', + 'rm' => 'audio/x-pn-realaudio', + 'rpm' => 'audio/x-pn-realaudio-plugin', + 'ra' => 'audio/x-realaudio', + 'rv' => 'video/vnd.rn-realvideo', + 'wav' => ['audio/x-wav', 'audio/wave', 'audio/wav'], + 'bmp' => [ + 'image/bmp', + 'image/x-bmp', + 'image/x-bitmap', + 'image/x-xbitmap', + 'image/x-win-bitmap', + 'image/x-windows-bmp', + 'image/ms-bmp', + 'image/x-ms-bmp', + 'application/bmp', + 'application/x-bmp', + 'application/x-win-bitmap', + ], + 'gif' => 'image/gif', + 'jpeg' => 'image/jpeg', + 'jpg' => 'image/jpeg', + 'jpe' => 'image/jpeg', + 'png' => ['image/png', 'image/x-png'], + 'tiff' => 'image/tiff', + 'tif' => 'image/tiff', + 'css' => ['text/css', 'text/plain'], + 'html' => ['text/html', 'text/plain'], + 'htm' => ['text/html', 'text/plain'], + 'shtml' => ['text/html', 'text/plain'], + 'txt' => 'text/plain', + 'text' => 'text/plain', + 'log' => ['text/plain', 'text/x-log'], + 'rtx' => 'text/richtext', + 'rtf' => 'text/rtf', + 'xml' => ['application/xml', 'text/xml', 'text/plain'], + 'xsl' => ['application/xml', 'text/xsl', 'text/xml'], + 'mpeg' => 'video/mpeg', + 'mpg' => 'video/mpeg', + 'mpe' => 'video/mpeg', + 'qt' => 'video/quicktime', + 'mov' => 'video/quicktime', + 'avi' => ['video/x-msvideo', 'video/msvideo', 'video/avi', 'application/x-troff-msvideo'], + 'movie' => 'video/x-sgi-movie', + 'doc' => ['application/msword', 'application/vnd.ms-office'], + 'docx' => [ + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'application/zip', + 'application/msword', + 'application/x-zip', + ], + 'dot' => ['application/msword', 'application/vnd.ms-office'], + 'dotx' => [ + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'application/zip', + 'application/msword', + ], + 'xlsx' => [ + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'application/zip', + 'application/vnd.ms-excel', + 'application/msword', + 'application/x-zip', + ], + 'word' => ['application/msword', 'application/octet-stream'], + 'xl' => 'application/excel', + 'eml' => 'message/rfc822', + 'json' => ['application/json', 'text/json'], + 'pem' => ['application/x-x509-user-cert', 'application/x-pem-file', 'application/octet-stream'], + 'p10' => ['application/x-pkcs10', 'application/pkcs10'], + 'p12' => 'application/x-pkcs12', + 'p7a' => 'application/x-pkcs7-signature', + 'p7c' => ['application/pkcs7-mime', 'application/x-pkcs7-mime'], + 'p7m' => ['application/pkcs7-mime', 'application/x-pkcs7-mime'], + 'p7r' => 'application/x-pkcs7-certreqresp', + 'p7s' => 'application/pkcs7-signature', + 'crt' => ['application/x-x509-ca-cert', 'application/x-x509-user-cert', 'application/pkix-cert'], + 'crl' => ['application/pkix-crl', 'application/pkcs-crl'], + 'der' => 'application/x-x509-ca-cert', + 'kdb' => 'application/octet-stream', + 'pgp' => 'application/pgp', + 'gpg' => 'application/gpg-keys', + 'sst' => 'application/octet-stream', + 'csr' => 'application/octet-stream', + 'rsa' => 'application/x-pkcs7', + 'cer' => ['application/pkix-cert', 'application/x-x509-ca-cert'], + '3g2' => 'video/3gpp2', + '3gp' => 'video/3gp', + 'mp4' => 'video/mp4', + 'm4a' => 'audio/x-m4a', + 'f4v' => 'video/mp4', + 'webm' => 'video/webm', + 'aac' => 'audio/x-acc', + 'm4u' => 'application/vnd.mpegurl', + 'm3u' => 'text/plain', + 'xspf' => 'application/xspf+xml', + 'vlc' => 'application/videolan', + 'wmv' => ['video/x-ms-wmv', 'video/x-ms-asf'], + 'au' => 'audio/x-au', + 'ac3' => 'audio/ac3', + 'flac' => 'audio/x-flac', + 'ogg' => 'audio/ogg', + 'kmz' => ['application/vnd.google-earth.kmz', 'application/zip', 'application/x-zip'], + 'kml' => ['application/vnd.google-earth.kml+xml', 'application/xml', 'text/xml'], + 'ics' => 'text/calendar', + 'ical' => 'text/calendar', + 'zsh' => 'text/x-scriptzsh', + '7zip' => [ + 'application/x-compressed', + 'application/x-zip-compressed', + 'application/zip', + 'multipart/x-zip', + ], + 'cdr' => [ + 'application/cdr', + 'application/coreldraw', + 'application/x-cdr', + 'application/x-coreldraw', + 'image/cdr', + 'image/x-cdr', + 'zz-application/zz-winassoc-cdr', + ], + 'wma' => ['audio/x-ms-wma', 'video/x-ms-asf'], + 'jar' => [ + 'application/java-archive', + 'application/x-java-application', + 'application/x-jar', + 'application/x-compressed', + ], + 'svg' => ['image/svg+xml', 'application/xml', 'text/xml'], + 'vcf' => 'text/x-vcard', + 'ttf' => ['application/x-font-ttf', 'application/x-font-truetype'], + 'otf' => 'application/x-font-opentype', + 'woff' => 'application/font-woff', + 'woff2' => 'application/font-woff2', + 'eot' => 'application/vnd.ms-fontobject', + 'sfnt' => 'application/font-sfnt', + 'ico' => 'image/x-icon', ]; \ No newline at end of file diff --git a/src/Directory.php b/src/Directory.php index aed9bd4..7cdb940 100644 --- a/src/Directory.php +++ b/src/Directory.php @@ -1,257 +1,257 @@ -getPathName() : $dir; - - if (is_dir($dir)) { - return new SplDirectoryInfo($dir); - } elseif (null !== ($pathName = $this->getPathName())) { - if (mkdir( - $makeDirectory = $pathName . DIRECTORY_SEPARATOR . str_replace( - ['\\', '/'], - DIRECTORY_SEPARATOR, - $dir - ), - $mode, - $recursive - )) { - return new SplDirectoryInfo($makeDirectory); - } - } elseif (mkdir( - $makeDirectory = str_replace(['\\', '/'], DIRECTORY_SEPARATOR, $dir), - $mode, - $recursive - )) { - return new SplDirectoryInfo($makeDirectory); - } - - return false; - } - - // ------------------------------------------------------------------------ - - /** - * Directory::delete - * - * Remove a directory. - * - * @param bool $fileOnly Remove files only and keep the directory structure. - * - * @return bool Returns TRUE on success or FALSE on failure. - */ - public function delete($fileOnly = false) - { - return $this->recursiveDelete($this->getRealPath(), $fileOnly); - } - - // ------------------------------------------------------------------------ - - /** - * Directory::recursiveDelete - * - * @param string $dir Directory path. - * @param bool $fileOnly Remove files only and keep the directory structure. - * - * @return bool Returns TRUE on success or FALSE on failure. - */ - private function recursiveDelete($dir, $fileOnly = false) - { - $dir = realpath($dir); - - if (is_dir($dir)) { - $iterator = new \RecursiveDirectoryIterator($dir, \RecursiveDirectoryIterator::SKIP_DOTS); - $files = new \RecursiveIteratorIterator($iterator, \RecursiveIteratorIterator::CHILD_FIRST); - foreach ($files as $file) { - if ($file->isDir()) { - $this->recursiveDelete($file->getRealPath(), $fileOnly); - } elseif ($file->isFile()) { - unlink($file->getRealPath()); - } - } - - if ($fileOnly === false) { - rmdir($dir); - } - - return true; - } - - return false; - } - - // ------------------------------------------------------------------------ - - /** - * Directory::setGroup - * - * Attempts to change the group of the directory to group. - * - * Only the superuser may change the group of a directory arbitrarily; other users may change the group of a file - * to any group of which that user is a member. - * - * @param mixed $group A group name or number. - * - * @return bool Returns TRUE on success or FALSE on failure. - */ - public function setGroup($group) - { - $params[] = $this->getRealPath(); - $params[] = $group; - - return call_user_func_array('chgrp', $params); - } - - // ------------------------------------------------------------------------ - - /** - * Directory::setMode - * - * Attempts to change the mode of the specified file to that given in mode. - * - * @param int $mode The mode parameter consists of three octal number components specifying access restrictions for - * the owner, the user group in which the owner is in, and to everybody else in this order. One - * component can be computed by adding up the needed permissions for that target user base. Number - * 1 means that you grant execute rights, number 2 means that you make the directory writable, - * number - * 4 means that you make the directory readable. Add up these numbers to specify needed rights. - * You can also read more about modes on Unix systems with 'man 1 chmod' and 'man 2 chmod'. - * - * @return bool Returns TRUE on success or FALSE on failure. - */ - public function setMode($mode) - { - $params[] = $this->getRealPath(); - $params[] = $mode; - - return call_user_func_array('chmod', $params); - } - - // ------------------------------------------------------------------------ - - /** - * Directory::setOwner - * - * Attempts to change the owner of the directory to user user. - * Only the superuser may change the owner of a directory. - * - * @param mixed $user A user name or number. - * - * @return bool Returns TRUE on success or FALSE on failure. - */ - public function setOwner($user) - { - $params[] = $this->getRealPath(); - $params[] = $user; - - return call_user_func_array('chown', $params); - } - - // ------------------------------------------------------------------------ - - /** - * Directory::findFilesByExtension - * - * Find files by extension. - * - * @param string $extension - * - * @return array - */ - public function findFilesByExtension($extension) - { - $extension = trim($extension, '.'); - - $directoryIterator = new \RecursiveIteratorIterator( - new \RecursiveDirectoryIterator($this->getRealPath()), - \RecursiveIteratorIterator::SELF_FIRST - ); - - $result = []; - - foreach ($directoryIterator as $directoryFile) { - if ($directoryFile->isFile()) { - if ($extension === '*') { - array_push($result, $directoryFile->getFilename()); - } elseif (preg_match('/\.' . $extension . '$/ui', $directoryFile->getFilename())) { - if ( ! in_array($directoryFile->getRealPath(), $result)) { - array_push($result, $directoryFile->getRealPath()); - } - } - } - } - - return $result; - } - - // ------------------------------------------------------------------------ - - /** - * Directory::findFilesByFilename - * - * Find Files By Filename - * - * @param string $filename - * - * @return array - */ - public function findFilesByFilename($filename) - { - $directoryIterator = new \RecursiveIteratorIterator( - new \RecursiveDirectoryIterator($this->getRealPath()), - \RecursiveIteratorIterator::SELF_FIRST - ); - - $result = []; - - foreach ($directoryIterator as $directoryFile) { - if ($directoryFile->isFile()) { - if (preg_match('/\\' . $filename . '.*/ui', $directoryFile->getFilename()) OR - preg_match('/\\' . ucfirst($filename) . '.*/ui', $directoryFile->getFilename()) - ) { - if ( ! in_array($directoryFile->getRealPath(), $result)) { - array_push($result, $directoryFile->getRealPath()); - } - } - } - } - - return $result; - } -} - +getPathName() : $dir; + + if (is_dir($dir)) { + return new SplDirectoryInfo($dir); + } elseif (null !== ($pathName = $this->getPathName())) { + if (mkdir( + $makeDirectory = $pathName . DIRECTORY_SEPARATOR . str_replace( + ['\\', '/'], + DIRECTORY_SEPARATOR, + $dir + ), + $mode, + $recursive + )) { + return new SplDirectoryInfo($makeDirectory); + } + } elseif (mkdir( + $makeDirectory = str_replace(['\\', '/'], DIRECTORY_SEPARATOR, $dir), + $mode, + $recursive + )) { + return new SplDirectoryInfo($makeDirectory); + } + + return false; + } + + // ------------------------------------------------------------------------ + + /** + * Directory::delete + * + * Remove a directory. + * + * @param bool $fileOnly Remove files only and keep the directory structure. + * + * @return bool Returns TRUE on success or FALSE on failure. + */ + public function delete($fileOnly = false) + { + return $this->recursiveDelete($this->getRealPath(), $fileOnly); + } + + // ------------------------------------------------------------------------ + + /** + * Directory::recursiveDelete + * + * @param string $dir Directory path. + * @param bool $fileOnly Remove files only and keep the directory structure. + * + * @return bool Returns TRUE on success or FALSE on failure. + */ + private function recursiveDelete($dir, $fileOnly = false) + { + $dir = realpath($dir); + + if (is_dir($dir)) { + $iterator = new \RecursiveDirectoryIterator($dir, \RecursiveDirectoryIterator::SKIP_DOTS); + $files = new \RecursiveIteratorIterator($iterator, \RecursiveIteratorIterator::CHILD_FIRST); + foreach ($files as $file) { + if ($file->isDir()) { + $this->recursiveDelete($file->getRealPath(), $fileOnly); + } elseif ($file->isFile()) { + unlink($file->getRealPath()); + } + } + + if ($fileOnly === false) { + rmdir($dir); + } + + return true; + } + + return false; + } + + // ------------------------------------------------------------------------ + + /** + * Directory::setGroup + * + * Attempts to change the group of the directory to group. + * + * Only the superuser may change the group of a directory arbitrarily; other users may change the group of a file + * to any group of which that user is a member. + * + * @param mixed $group A group name or number. + * + * @return bool Returns TRUE on success or FALSE on failure. + */ + public function setGroup($group) + { + $params[] = $this->getRealPath(); + $params[] = $group; + + return call_user_func_array('chgrp', $params); + } + + // ------------------------------------------------------------------------ + + /** + * Directory::setMode + * + * Attempts to change the mode of the specified file to that given in mode. + * + * @param int $mode The mode parameter consists of three octal number components specifying access restrictions for + * the owner, the user group in which the owner is in, and to everybody else in this order. One + * component can be computed by adding up the needed permissions for that target user base. Number + * 1 means that you grant execute rights, number 2 means that you make the directory writable, + * number + * 4 means that you make the directory readable. Add up these numbers to specify needed rights. + * You can also read more about modes on Unix systems with 'man 1 chmod' and 'man 2 chmod'. + * + * @return bool Returns TRUE on success or FALSE on failure. + */ + public function setMode($mode) + { + $params[] = $this->getRealPath(); + $params[] = $mode; + + return call_user_func_array('chmod', $params); + } + + // ------------------------------------------------------------------------ + + /** + * Directory::setOwner + * + * Attempts to change the owner of the directory to user user. + * Only the superuser may change the owner of a directory. + * + * @param mixed $user A user name or number. + * + * @return bool Returns TRUE on success or FALSE on failure. + */ + public function setOwner($user) + { + $params[] = $this->getRealPath(); + $params[] = $user; + + return call_user_func_array('chown', $params); + } + + // ------------------------------------------------------------------------ + + /** + * Directory::findFilesByExtension + * + * Find files by extension. + * + * @param string $extension + * + * @return array + */ + public function findFilesByExtension($extension) + { + $extension = trim($extension, '.'); + + $directoryIterator = new \RecursiveIteratorIterator( + new \RecursiveDirectoryIterator($this->getRealPath()), + \RecursiveIteratorIterator::SELF_FIRST + ); + + $result = []; + + foreach ($directoryIterator as $directoryFile) { + if ($directoryFile->isFile()) { + if ($extension === '*') { + array_push($result, $directoryFile->getFilename()); + } elseif (preg_match('/\.' . $extension . '$/ui', $directoryFile->getFilename())) { + if ( ! in_array($directoryFile->getRealPath(), $result)) { + array_push($result, $directoryFile->getRealPath()); + } + } + } + } + + return $result; + } + + // ------------------------------------------------------------------------ + + /** + * Directory::findFilesByFilename + * + * Find Files By Filename + * + * @param string $filename + * + * @return array + */ + public function findFilesByFilename($filename) + { + $directoryIterator = new \RecursiveIteratorIterator( + new \RecursiveDirectoryIterator($this->getRealPath()), + \RecursiveIteratorIterator::SELF_FIRST + ); + + $result = []; + + foreach ($directoryIterator as $directoryFile) { + if ($directoryFile->isFile()) { + if (preg_match('/\\' . $filename . '.*/ui', $directoryFile->getFilename()) OR + preg_match('/\\' . ucfirst($filename) . '.*/ui', $directoryFile->getFilename()) + ) { + if ( ! in_array($directoryFile->getRealPath(), $result)) { + array_push($result, $directoryFile->getRealPath()); + } + } + } + } + + return $result; + } +} + diff --git a/src/File.php b/src/File.php index 1196d75..5235aa2 100644 --- a/src/File.php +++ b/src/File.php @@ -15,6 +15,7 @@ // ------------------------------------------------------------------------ +use O2System\Filesystem\Handlers\Stream; use O2System\Spl\Info\SplFileInfo; /** @@ -448,4 +449,17 @@ public function delete($context = null) return call_user_func_array('unlink', $params); } + + // ------------------------------------------------------------------------ + + /** + * File::getStream + * + * @param string $mode + * @return Stream + */ + public function getStream($mode = 'rb') + { + return new Stream($this, $mode); + } } \ No newline at end of file diff --git a/src/Files/CsvFile.php b/src/Files/CsvFile.php index 42c3dde..5b7e786 100644 --- a/src/Files/CsvFile.php +++ b/src/Files/CsvFile.php @@ -1,98 +1,98 @@ -filePath - : $filePath; - - $defaultOptions = [ - 'length' => 1000, - 'delimiter' => ',', - ]; - - $options = array_merge($defaultOptions, $options); - - $result = []; - - if (false !== ($handle = fopen($filePath, 'r'))) { - while (false !== ($data = fgetcsv($handle, $options[ 'length' ], $options[ 'delimiter' ]))) { - $result[] = fgetcsv($handle); - } - } - - return $result; - } - - // ------------------------------------------------------------------------ - - /** - * CsvFile::writeFile - * - * @param string $filePath Path to the file. - * @param array $options Write file options. - * - * @return bool Returns TRUE on success or FALSE on failure. - */ - public function writeFile($filePath = null, array $options = []) - { - $filePath = empty($filePath) - ? $this->filePath - : $filePath; - - $handle = (new File())->create($filePath); - - foreach ($this->getArrayCopy() as $key => $value) { - if ( ! is_array($value)) { - $list = [$key, $value]; - } else { - $list = $value; - } - fputcsv($handle, $list); - } - - return fclose($handle); - } +filePath + : $filePath; + + $defaultOptions = [ + 'length' => 1000, + 'delimiter' => ',', + ]; + + $options = array_merge($defaultOptions, $options); + + $result = []; + + if (false !== ($handle = fopen($filePath, 'r'))) { + while (false !== ($data = fgetcsv($handle, $options[ 'length' ], $options[ 'delimiter' ]))) { + $result[] = fgetcsv($handle); + } + } + + return $result; + } + + // ------------------------------------------------------------------------ + + /** + * CsvFile::writeFile + * + * @param string $filePath Path to the file. + * @param array $options Write file options. + * + * @return bool Returns TRUE on success or FALSE on failure. + */ + public function writeFile($filePath = null, array $options = []) + { + $filePath = empty($filePath) + ? $this->filePath + : $filePath; + + $handle = (new File())->create($filePath); + + foreach ($this->getArrayCopy() as $key => $value) { + if ( ! is_array($value)) { + $list = [$key, $value]; + } else { + $list = $value; + } + fputcsv($handle, $list); + } + + return fclose($handle); + } } \ No newline at end of file diff --git a/src/Files/IniFile.php b/src/Files/IniFile.php index 228291f..f1acc23 100644 --- a/src/Files/IniFile.php +++ b/src/Files/IniFile.php @@ -1,130 +1,130 @@ -merge($items); - - return $items; - } - - // ------------------------------------------------------------------------ - - /** - * IniFile::writeFile - * - * @param string $filePath Path to the file. - * @param array $options Write file options. - * - * @return bool Returns TRUE on success or FALSE on failure. - */ - public function writeFile($filePath = null, array $options = []) - { - $filePath = empty($filePath) - ? $this->filePath - : $filePath; - - $sections = (empty($options) - ? true - : $options[ 'sections' ]); - - $content = null; - - if ($sections) { - foreach ($this->getArrayCopy() as $section => $data) { - if (is_array($data)) { - $content .= '[' . $section . ']' . PHP_EOL; - - foreach ($data as $key => $value) { - if (is_array($value)) { - foreach ($value as $valueChild) { - $content .= $key . '[] = ' . (is_numeric($valueChild) - ? $valueChild - : '"' . $valueChild . '"') . PHP_EOL; - } - } elseif (strpos($key, ';') !== false) { - $content .= '; ' . trim(ucfirst($key), ';') . ' ' . $value . PHP_EOL; - } elseif (empty($value)) { - $content .= $key . ' = ' . PHP_EOL; - } else { - $content .= $key . ' = ' . (is_numeric($value) - ? $value - : '"' . $value . '"') . PHP_EOL; - } - } - - $content .= PHP_EOL; - } elseif (strpos($section, ';') !== false) { - $content .= '; ' . trim(ucfirst($section), ';') . ' ' . $data . PHP_EOL; - } elseif (empty($data)) { - $content .= $section . ' = ' . PHP_EOL; - } else { - $content .= $section . ' = ' . (is_numeric($data) - ? $data - : '"' . $data . '"') . PHP_EOL; - } - } - } else { - foreach ($this->getArrayCopy() as $key => $value) { - if (is_array($value)) { - foreach ($value as $valueChild) { - $content .= $key . '[] = ' . (is_numeric($valueChild) - ? $valueChild - : '"' . $valueChild . '"') . PHP_EOL; - } - } elseif (strpos($key, ';') !== false) { - $content .= '; ' . trim(ucfirst($key), ';') . ' ' . $value . PHP_EOL; - } elseif (empty($value)) { - $content .= $key . ' = ' . PHP_EOL; - } else { - $content .= $key . ' = ' . (is_numeric($value) - ? $value - : '"' . $value . '"') . PHP_EOL; - } - } - } - - return (new File())->write($filePath, $content); - } +merge($items); + + return $items; + } + + // ------------------------------------------------------------------------ + + /** + * IniFile::writeFile + * + * @param string $filePath Path to the file. + * @param array $options Write file options. + * + * @return bool Returns TRUE on success or FALSE on failure. + */ + public function writeFile($filePath = null, array $options = []) + { + $filePath = empty($filePath) + ? $this->filePath + : $filePath; + + $sections = (empty($options) + ? true + : $options[ 'sections' ]); + + $content = null; + + if ($sections) { + foreach ($this->getArrayCopy() as $section => $data) { + if (is_array($data)) { + $content .= '[' . $section . ']' . PHP_EOL; + + foreach ($data as $key => $value) { + if (is_array($value)) { + foreach ($value as $valueChild) { + $content .= $key . '[] = ' . (is_numeric($valueChild) + ? $valueChild + : '"' . $valueChild . '"') . PHP_EOL; + } + } elseif (strpos($key, ';') !== false) { + $content .= '; ' . trim(ucfirst($key), ';') . ' ' . $value . PHP_EOL; + } elseif (empty($value)) { + $content .= $key . ' = ' . PHP_EOL; + } else { + $content .= $key . ' = ' . (is_numeric($value) + ? $value + : '"' . $value . '"') . PHP_EOL; + } + } + + $content .= PHP_EOL; + } elseif (strpos($section, ';') !== false) { + $content .= '; ' . trim(ucfirst($section), ';') . ' ' . $data . PHP_EOL; + } elseif (empty($data)) { + $content .= $section . ' = ' . PHP_EOL; + } else { + $content .= $section . ' = ' . (is_numeric($data) + ? $data + : '"' . $data . '"') . PHP_EOL; + } + } + } else { + foreach ($this->getArrayCopy() as $key => $value) { + if (is_array($value)) { + foreach ($value as $valueChild) { + $content .= $key . '[] = ' . (is_numeric($valueChild) + ? $valueChild + : '"' . $valueChild . '"') . PHP_EOL; + } + } elseif (strpos($key, ';') !== false) { + $content .= '; ' . trim(ucfirst($key), ';') . ' ' . $value . PHP_EOL; + } elseif (empty($value)) { + $content .= $key . ' = ' . PHP_EOL; + } else { + $content .= $key . ' = ' . (is_numeric($value) + ? $value + : '"' . $value . '"') . PHP_EOL; + } + } + } + + return (new File())->write($filePath, $content); + } } \ No newline at end of file diff --git a/src/Files/JsonFile.php b/src/Files/JsonFile.php index 0cd0933..b659855 100644 --- a/src/Files/JsonFile.php +++ b/src/Files/JsonFile.php @@ -1,79 +1,79 @@ -filePath - : $filePath; - - $result = new ArrayIterator(); - - if (false !== ($contents = json_decode(file_get_contents($filePath), true))) { - if (json_last_error() === JSON_ERROR_NONE) { - foreach ($contents as $content) { - $result[] = new SplArrayObject($content); - } - } - } - - return $result; - } - - // ------------------------------------------------------------------------ - - /** - * JsonFile::writeFile - * - * @param string $filePath Path to the file. - * @param array $options Write file options. - * - * @return bool Returns TRUE on success or FALSE on failure. - */ - public function writeFile($filePath = null, array $options = []) - { - $filePath = empty($filePath) - ? $this->filePath - : $filePath; - - if ($this->count()) { - return (new File())->write($filePath, json_encode($this->getArrayCopy(), JSON_PRETTY_PRINT)); - } - } +filePath + : $filePath; + + $result = new ArrayIterator(); + + if (false !== ($contents = json_decode(file_get_contents($filePath), true))) { + if (json_last_error() === JSON_ERROR_NONE) { + foreach ($contents as $content) { + $result[] = new SplArrayObject($content); + } + } + } + + return $result; + } + + // ------------------------------------------------------------------------ + + /** + * JsonFile::writeFile + * + * @param string $filePath Path to the file. + * @param array $options Write file options. + * + * @return bool Returns TRUE on success or FALSE on failure. + */ + public function writeFile($filePath = null, array $options = []) + { + $filePath = empty($filePath) + ? $this->filePath + : $filePath; + + if ($this->count()) { + return (new File())->write($filePath, json_encode($this->getArrayCopy(), JSON_PRETTY_PRINT)); + } + } } \ No newline at end of file diff --git a/src/Files/XmlFile.php b/src/Files/XmlFile.php index f73b806..260d903 100644 --- a/src/Files/XmlFile.php +++ b/src/Files/XmlFile.php @@ -1,91 +1,91 @@ -filePath - : $filePath; - - $result = new ArrayIterator(); - - if (false !== ($xml = simplexml_load_file($filePath))) { - $contents = json_decode(json_encode($xml), true); // force to array conversion - - if (count($contents) == 1) { - $contents = reset($contents); - } - - if (json_last_error() === JSON_ERROR_NONE) { - foreach ($contents as $content) { - $result[] = new SplArrayObject($content); - } - } - } - - return $result; - } - - // ------------------------------------------------------------------------ - - /** - * XmlFile::writeFile - * - * @param string $filePath Path to the file. - * @param array $options Write file options. - * - * @return bool Returns TRUE on success or FALSE on failure. - */ - public function writeFile($filePath = null, array $options = []) - { - $filePath = empty($filePath) - ? $this->filePath - : $filePath; - - if ($this->count()) { - $root = '<' . pathinfo($filePath, PATHINFO_FILENAME) . '/>'; - - $contents = $this->getArrayCopy(); - $xml = new \SimpleXMLElement($root); - array_walk_recursive($contents, [&$xml, 'addChild']); - - return (new File())->write($filePath, $xml->asXML()); - } - } +filePath + : $filePath; + + $result = new ArrayIterator(); + + if (false !== ($xml = simplexml_load_file($filePath))) { + $contents = json_decode(json_encode($xml), true); // force to array conversion + + if (count($contents) == 1) { + $contents = reset($contents); + } + + if (json_last_error() === JSON_ERROR_NONE) { + foreach ($contents as $content) { + $result[] = new SplArrayObject($content); + } + } + } + + return $result; + } + + // ------------------------------------------------------------------------ + + /** + * XmlFile::writeFile + * + * @param string $filePath Path to the file. + * @param array $options Write file options. + * + * @return bool Returns TRUE on success or FALSE on failure. + */ + public function writeFile($filePath = null, array $options = []) + { + $filePath = empty($filePath) + ? $this->filePath + : $filePath; + + if ($this->count()) { + $root = '<' . pathinfo($filePath, PATHINFO_FILENAME) . '/>'; + + $contents = $this->getArrayCopy(); + $xml = new \SimpleXMLElement($root); + array_walk_recursive($contents, [&$xml, 'addChild']); + + return (new File())->write($filePath, $xml->asXML()); + } + } } \ No newline at end of file diff --git a/src/Files/ZipFile.php b/src/Files/ZipFile.php index a89ae2e..dc36c6d 100644 --- a/src/Files/ZipFile.php +++ b/src/Files/ZipFile.php @@ -1,183 +1,183 @@ -filePath - : $filePath; - - - $result = []; - - if (extension_loaded('zip')) { - if ($zipHandle = zip_open($filePath)) { - while ($zipContent = zip_read($zipHandle)) { - $result[] = zip_entry_name($zipContent); - } - - zip_close($zipHandle); - } - } - - return $result; - } - - // ------------------------------------------------------------------------ - - /** - * ZipFile::writeFile - * - * @param string $filePath Path to the file. - * @param array $options Write file options. - * - * @return bool Returns TRUE on success or FALSE on failure. - */ - public function writeFile($filePath = null, array $options = []) - { - $filePath = empty($filePath) - ? $this->filePath - : $filePath; - - if ($this->count()) { - $zip = new \ZipArchive(); - - if ($zip->open($filePath, \ZipArchive::CREATE)) { - foreach ($this->getArrayCopy() as $directory => $files) { - if (is_array($files)) { - $zip->addEmptyDir($directory); - foreach ($files as $file) { - if (is_file($file)) { - $zip->addFile($file); - } - } - } elseif (is_file($files)) { - $zip->addFile($files); - } - } - - return $zip->close(); - } - } - - return false; - } - - // ------------------------------------------------------------------------ - - /** - * ZipFile::compress - * - * Zipped a folder (include itself). - * - * @param string $sourcePath Path of directory to be zip. - * @param string|null $filePath Path to the zip file. - */ - public function compress($sourcePath, $filePath = null) - { - $filePath = empty($filePath) - ? $this->filePath - : $filePath; - - $zip = new \ZipArchive(); - $zip->open($filePath, \ZipArchive::CREATE); - $zip->addEmptyDir(pathinfo($sourcePath, PATHINFO_BASENAME)); - $this->recursiveCompress($sourcePath, strlen(dirname($sourcePath, 2) . DIRECTORY_SEPARATOR), $zip); - $zip->close(); - } - - // ------------------------------------------------------------------------ - - /** - * ZipFile::recursiveCompress - * - * Add files and sub-directories in a folder to zip file. - * - * @param string $directory Path of directory to be zip. - * @param int $exclusiveLength Number of text to be exclusive from the file path. - * @param \ZipArchive $zipArchive Zip Archive instance. - */ - private function recursiveCompress($directory, $exclusiveLength, &$zipArchive) - { - $handle = opendir($directory); - - while (false !== ($file = readdir($handle))) { - if ($file != '.' && $file != '..') { - $filePath = "$directory/$file"; - // Remove prefix from file path before add to zip. - $localPath = substr($filePath, $exclusiveLength); - if (is_file($filePath)) { - $zipArchive->addFile($filePath, $localPath); - } elseif (is_dir($filePath)) { - // Add sub-directory. - $zipArchive->addEmptyDir($localPath); - $this->recursiveCompress($filePath, $exclusiveLength, $zipArchive); - } - } - } - closedir($handle); - } - - // ------------------------------------------------------------------------ - - /** - * ZipFile::extract - * - * Extract a zip file. - * - * @param string $destinationPath Path of unzip directory. - * - * @return bool Returns TRUE on success or FALSE on failure. - */ - public function extract($destinationPath) - { - if (extension_loaded('zip')) { - if (is_file($this->filePath)) { - $zip = new \ZipArchive; - $contents = $zip->open($this->filePath); - - if ($contents === true) { - if (is_dir($destinationPath)) { - $zip->extractTo($destinationPath); - $zip->close(); - - return true; - } - } - } - } - - return false; - } +filePath + : $filePath; + + + $result = []; + + if (extension_loaded('zip')) { + if ($zipHandle = zip_open($filePath)) { + while ($zipContent = zip_read($zipHandle)) { + $result[] = zip_entry_name($zipContent); + } + + zip_close($zipHandle); + } + } + + return $result; + } + + // ------------------------------------------------------------------------ + + /** + * ZipFile::writeFile + * + * @param string $filePath Path to the file. + * @param array $options Write file options. + * + * @return bool Returns TRUE on success or FALSE on failure. + */ + public function writeFile($filePath = null, array $options = []) + { + $filePath = empty($filePath) + ? $this->filePath + : $filePath; + + if ($this->count()) { + $zip = new \ZipArchive(); + + if ($zip->open($filePath, \ZipArchive::CREATE)) { + foreach ($this->getArrayCopy() as $directory => $files) { + if (is_array($files)) { + $zip->addEmptyDir($directory); + foreach ($files as $file) { + if (is_file($file)) { + $zip->addFile($file); + } + } + } elseif (is_file($files)) { + $zip->addFile($files); + } + } + + return $zip->close(); + } + } + + return false; + } + + // ------------------------------------------------------------------------ + + /** + * ZipFile::compress + * + * Zipped a folder (include itself). + * + * @param string $sourcePath Path of directory to be zip. + * @param string|null $filePath Path to the zip file. + */ + public function compress($sourcePath, $filePath = null) + { + $filePath = empty($filePath) + ? $this->filePath + : $filePath; + + $zip = new \ZipArchive(); + $zip->open($filePath, \ZipArchive::CREATE); + $zip->addEmptyDir(pathinfo($sourcePath, PATHINFO_BASENAME)); + $this->recursiveCompress($sourcePath, strlen(dirname($sourcePath, 2) . DIRECTORY_SEPARATOR), $zip); + $zip->close(); + } + + // ------------------------------------------------------------------------ + + /** + * ZipFile::recursiveCompress + * + * Add files and sub-directories in a folder to zip file. + * + * @param string $directory Path of directory to be zip. + * @param int $exclusiveLength Number of text to be exclusive from the file path. + * @param \ZipArchive $zipArchive Zip Archive instance. + */ + private function recursiveCompress($directory, $exclusiveLength, &$zipArchive) + { + $handle = opendir($directory); + + while (false !== ($file = readdir($handle))) { + if ($file != '.' && $file != '..') { + $filePath = "$directory/$file"; + // Remove prefix from file path before add to zip. + $localPath = substr($filePath, $exclusiveLength); + if (is_file($filePath)) { + $zipArchive->addFile($filePath, $localPath); + } elseif (is_dir($filePath)) { + // Add sub-directory. + $zipArchive->addEmptyDir($localPath); + $this->recursiveCompress($filePath, $exclusiveLength, $zipArchive); + } + } + } + closedir($handle); + } + + // ------------------------------------------------------------------------ + + /** + * ZipFile::extract + * + * Extract a zip file. + * + * @param string $destinationPath Path of unzip directory. + * + * @return bool Returns TRUE on success or FALSE on failure. + */ + public function extract($destinationPath) + { + if (extension_loaded('zip')) { + if (is_file($this->filePath)) { + $zip = new \ZipArchive; + $contents = $zip->open($this->filePath); + + if ($contents === true) { + if (is_dir($destinationPath)) { + $zip->extractTo($destinationPath); + $zip->close(); + + return true; + } + } + } + } + + return false; + } } \ No newline at end of file diff --git a/src/Handlers/Ftp.php b/src/Handlers/Ftp.php index 3020a03..74097d3 100644 --- a/src/Handlers/Ftp.php +++ b/src/Handlers/Ftp.php @@ -1,632 +1,632 @@ -setConfig($config); - - // Prep the port - $this->config[ 'port' ] = empty($this->config[ 'port' ]) ? 21 : (int)$this->config[ 'port' ]; - - // Prep the hostname - $this->config[ 'hostname' ] = preg_replace('|.+?://|', '', $this->config[ 'hostname' ]); - - language() - ->addFilePath(str_replace('Handlers', '', __DIR__) . DIRECTORY_SEPARATOR) - ->loadFile('ftp'); - } - - // -------------------------------------------------------------------- - - /** - * Ftp::connect - * - * Connect to FTP server. - * - * @return bool Returns TRUE on success or FALSE on failure. - * @throws RuntimeException - */ - public function connect() - { - if (false === ($this->handle = @ftp_connect($this->config[ 'hostname' ], $this->config[ 'port' ]))) { - if ($this->debugMode === true) { - throw new RuntimeException('FTP_E_UNABLE_TO_CONNECT'); - } - - $this->addError(1, 'FTP_E_UNABLE_TO_CONNECT'); - - return false; - } - - if (false !== (@ftp_login($this->handle, $this->config[ 'username' ], $this->config[ 'password' ]))) { - if ($this->debugMode === true) { - throw new RuntimeException('FTP_E_UNABLE_TO_LOGIN'); - } - - $this->addError(2, 'FTP_E_UNABLE_TO_LOGIN'); - - return false; - } - - // Set passive mode if needed - if ($this->passiveMode === true) { - ftp_pasv($this->handle, true); - } - - return true; - } - - // -------------------------------------------------------------------- - - /** - * Ftp::download - * - * Download a file from a remote server to the local server - * - * @param string $remoteFilePath Remote file path. - * @param string $localFilePath Local destination file path. - * @param string $mode File transfer mode. - * - * @return bool Returns TRUE on success or FALSE on failure. - * @throws RuntimeException - */ - public function download($remoteFilePath, $localFilePath, $mode = 'auto') - { - if ( ! $this->isConnected()) { - return false; - } - - // Set the mode if not specified - if ($mode === 'auto') { - // Get the file extension so we can set the upload type - $ext = $this->getExtension($remoteFilePath); - $mode = $this->getTransferMode($ext); - } - - $mode = ($mode === 'ascii') ? FTP_ASCII : FTP_BINARY; - - $result = @ftp_get($this->handle, $localFilePath, $remoteFilePath, $mode); - - if ($result === false) { - if ($this->debugMode === true) { - throw new RuntimeException('FTP_E_UNABLE_TO_DOWNLOAD'); - } - - $this->addError(3, 'FTP_E_UNABLE_TO_DOWNLOAD'); - - return false; - } - - return true; - } - - // -------------------------------------------------------------------- - - /** - * Ftp::isConnected - * - * Validates the connection ID - * - * @return bool Returns TRUE on success or FALSE on failure. - * @throws RuntimeException - */ - protected function isConnected() - { - if ( ! is_resource($this->handle)) { - if ($this->debugMode === true) { - throw new RuntimeException('FTP_E_NO_CONNECTION'); - } - - $this->addError(4, 'FTP_E_NO_CONNECTION'); - - return false; - } - - return true; - } - - // -------------------------------------------------------------------- - - /** - * Ftp::getExtension - * - * Extract the file extension. - * - * @param string $filename String of filename to be extracted. - * - * @return string By default it's set into txt file extension. - */ - protected function getExtension($filename) - { - return (($dot = strrpos($filename, '.')) === false) - ? 'txt' - : substr($filename, $dot + 1); - } - - // -------------------------------------------------------------------- - - /** - * Ftp::getTransferMode - * - * Gets upload transfer mode. - * - * @param string $ext Filename extension. - * - * @return string By default it's set into ascii mode. - */ - protected function getTransferMode($ext) - { - return in_array( - $ext, - ['txt', 'text', 'php', 'phps', 'php4', 'js', 'css', 'htm', 'html', 'phtml', 'shtml', 'log', 'xml'], - true - ) - ? 'ascii' - : 'binary'; - } - - // -------------------------------------------------------------------- - - /** - * Ftp::rename - * - * Rename a file on ftp server. - * - * @param string $oldFilename Old filename. - * @param string $newFilename New filename. - * - * @return bool Returns TRUE on success or FALSE on failure. - * @throws RuntimeException - */ - public function rename($oldFilename, $newFilename) - { - if ( ! $this->isConnected()) { - return false; - } - - $result = @ftp_rename($this->handle, $oldFilename, $newFilename); - - if ($result === false) { - if ($this->debugMode === true) { - throw new RuntimeException('FTP_UNABLE_TO_RENAME'); - } - - $this->addError(5, 'FTP_UNABLE_TO_RENAME'); - - return false; - } - - return true; - } - - // -------------------------------------------------------------------- - - /** - * Ftp::moveFile - * - * Moves a file on the FTP server. - * - * @param string $oldRemoteFilePath Old file path on the FTP server. - * @param string $newRemoteFilePath New file path on the FTP server. - * - * @return bool Returns TRUE on success or FALSE on failure. - * @throws RuntimeException - */ - public function move($oldRemoteFilePath, $newRemoteFilePath) - { - if ( ! $this->isConnected()) { - return false; - } - - $result = @ftp_rename($this->handle, $oldRemoteFilePath, $newRemoteFilePath); - - if ($result === false) { - if ($this->debugMode === true) { - throw new RuntimeException('FTP_UNABLE_TO_MOVE'); - } - - $this->addError(6, 'FTP_UNABLE_TO_MOVE'); - - return false; - } - - return true; - } - - // -------------------------------------------------------------------- - - /** - * Ftp::deleteFile - * - * Deletes a file on the FTP server - * - * @param string $filePath Path to the file to be deleted. - * - * @return bool Returns TRUE on success or FALSE on failure. - * @throws RuntimeException - */ - public function deleteFile($filePath) - { - if ( ! $this->isConnected()) { - return false; - } - - $result = @ftp_delete($this->handle, $filePath); - - if ($result === false) { - if ($this->debugMode === true) { - throw new RuntimeException('FTP_E_UNABLE_TO_DELETE'); - } - - $this->addError(7, 'FTP_E_UNABLE_TO_DELETE'); - - return false; - } - - return true; - } - - // -------------------------------------------------------------------- - - /** - * Ftp::deleteDir - * - * Delete a folder and recursively delete everything (including sub-folders) - * contained within it on the FTP server. - * - * @param string $remotePath Path to the directory to be deleted on the FTP server. - * - * @return bool Returns TRUE on success or FALSE on failure. - * @throws RuntimeException - */ - public function deleteDir($remotePath) - { - if ( ! $this->isConnected()) { - return false; - } - - // Add a trailing slash to the file path if needed - $remotePath = preg_replace('/(.+?)\/*$/', '\\1/', $remotePath); - - $list = $this->getFiles($remotePath); - if ( ! empty($list)) { - for ($i = 0, $c = count($list); $i < $c; $i++) { - // If we can't delete the item it's probaly a directory, - // so we'll recursively call delete_dir() - if ( ! preg_match('#/\.\.?$#', $list[ $i ]) && ! @ftp_delete($this->handle, $list[ $i ])) { - $this->deleteDir($list[ $i ]); - } - } - } - - if (@ftp_rmdir($this->handle, $remotePath) === false) { - if ($this->debugMode === true) { - throw new RuntimeException('FTP_E_UNABLE_TO_DELETE_DIRECTORY'); - } - - $this->addError(8, 'FTP_E_UNABLE_TO_DELETE_DIRECTORY'); - - return false; - } - - return true; - } - - // -------------------------------------------------------------------- - - /** - * Ftp::getFiles - * - * FTP List files in the specified directory. - * - * @param string $remotePath Path to the remote directory. - * - * @return array|bool Returns array of files list or FALSE on failure. - * @throws RuntimeException - */ - public function getFiles($remotePath = '.') - { - return $this->isConnected() - ? ftp_nlist($this->handle, $remotePath) - : false; - } - - // -------------------------------------------------------------------- - - /** - * Ftp::mirror - * - * Read a directory and recreate it remotely. - * - * This function recursively reads a folder and everything it contains - * (including sub-folders) and creates a mirror via FTP based on it. - * Whatever the directory structure of the original file path will be - * recreated on the server. - * - * @param string $localPath Path to source with trailing slash - * @param string $remotePath Path to destination - include the base folder with trailing slash - * - * @return bool Returns TRUE on success or FALSE on failure. - * @throws RuntimeException - */ - public function mirror($localPath, $remotePath) - { - if ( ! $this->isConnected()) { - return false; - } - - // Open the local file path - if ($fp = @opendir($localPath)) { - // Attempt to open the remote file path and try to create it, if it doesn't exist - if ( ! $this->changeDir($remotePath, true) && ( ! $this->makeDir($remotePath) OR ! $this->changeDir( - $remotePath - )) - ) { - return false; - } - - // Recursively read the local directory - while (false !== ($file = readdir($fp))) { - if (is_dir($localPath . $file) && $file[ 0 ] !== '.') { - $this->mirror($localPath . $file . '/', $remotePath . $file . '/'); - } elseif ($file[ 0 ] !== '.') { - // Get the file extension so we can se the upload type - $ext = $this->getExtension($file); - $mode = $this->getTransferMode($ext); - - $this->upload($localPath . $file, $remotePath . $file, $mode); - } - } - - return true; - } - - return false; - } - - // -------------------------------------------------------------------- - - /** - * Ftp::changeDir - * - * The second parameter lets us momentarily turn off debugging so that - * this function can be used to test for the existence of a folder - * without throwing an error. There's no FTP equivalent to is_dir() - * so we do it by trying to change to a particular directory. - * Internally, this parameter is only used by the "mirror" function below. - * - * @param string $remotePath The remote directory path. - * @param bool $suppressDebug Suppress debug mode. - * - * @return bool Returns TRUE on success or FALSE on failure. - * @throws RuntimeException - */ - public function changeDir($remotePath, $suppressDebug = false) - { - if ( ! $this->isConnected()) { - return false; - } - - $result = @ftp_chdir($this->handle, $remotePath); - - if ($result === false) { - if ($this->debugMode === true AND $suppressDebug === false) { - throw new RuntimeException('FTP_E_UNABLE_TO_CHANGE_DIRECTORY'); - } - - $this->addError(9, 'FTP_E_UNABLE_TO_CHANGE_DIRECTORY'); - - return false; - } - - return true; - } - - // ------------------------------------------------------------------------ - - /** - * Ftp::makeDir - * - * Create a remote directory on the ftp server. - * - * @param string $remotePath The remote directory that will be created on ftp server. - * @param int $permissions The remote directory permissions. - * - * @return bool Returns TRUE on success or FALSE on failure. - * @throws RuntimeException - */ - public function makeDir($remotePath, $permissions = null) - { - if ($remotePath === '' OR ! $this->isConnected()) { - return false; - } - - $result = @ftp_mkdir($this->handle, $remotePath); - - if ($result === false) { - if ($this->debugMode === true) { - throw new RuntimeException('FTP_E_UNABLE_TO_MAKE_DIRECTORY'); - } - - $this->addError(10, 'FTP_E_UNABLE_TO_MAKE_DIRECTORY'); - - return false; - } - - // Set file permissions if needed - if ($permissions !== null) { - $this->setChmod($remotePath, (int)$permissions); - } - - return true; - } - - // -------------------------------------------------------------------- - - /** - * Ftp::setChmod - * - * Set remote file permissions. - * - * @param string $remotePath Path to the remote directory or file to be changed. - * @param int $mode Remote directory permissions mode. - * - * @return bool Returns TRUE on success or FALSE on failure. - * @throws RuntimeException - */ - public function setChmod($remotePath, $mode) - { - if ( ! $this->isConnected()) { - return false; - } - - if (@ftp_chmod($this->handle, $mode, $remotePath) === false) { - if ($this->debugMode === true) { - throw new RuntimeException('FTP_E_UNABLE_TO_CHMOD'); - } - - $this->addError(11, 'FTP_E_UNABLE_TO_CHMOD'); - - return false; - } - - return true; - } - - // -------------------------------------------------------------------- - - /** - * Ftp::upload - * - * Uploader a file to the ftp server. - * - * @param string $localFilePath Local source file path. - * @param string $remoteFilePath Remote destination file path. - * @param string $mode File transfer mode. - * @param int $permissions Remote file permissions. - * - * @return bool Returns TRUE on success or FALSE on failure. - * @throws RuntimeException - */ - public function upload($localFilePath, $remoteFilePath, $mode = 'auto', $permissions = null) - { - if ( ! $this->isConnected()) { - return false; - } - - if (is_file($localFilePath)) { - // Set the mode if not specified - if ($mode === 'auto') { - // Get the file extension so we can set the upload type - $ext = $this->getExtension($localFilePath); - $mode = $this->getTransferMode($ext); - } - - $mode = ($mode === 'ascii') ? FTP_ASCII : FTP_BINARY; - - $result = @ftp_put($this->handle, $remoteFilePath, $localFilePath, $mode); - - if ($result === false) { - if ($this->debugMode === true) { - throw new RuntimeException('FTP_E_UNABLE_TO_UPLOAD'); - } - - $this->addError(12, 'FTP_E_UNABLE_TO_UPLOAD'); - - return false; - } - - // Set file permissions if needed - if ($permissions !== null) { - $this->setChmod($remoteFilePath, (int)$permissions); - } - - return true; - } - - return false; - } - - // ------------------------------------------------------------------------ - - /** - * Ftp::close - * - * Close the current ftp connection. - * - * @return bool Returns TRUE on success or FALSE on failure. - * @throws RuntimeException - */ - public function close() - { - return $this->isConnected() - ? @ftp_close($this->handle) - : false; - } +setConfig($config); + + // Prep the port + $this->config[ 'port' ] = empty($this->config[ 'port' ]) ? 21 : (int)$this->config[ 'port' ]; + + // Prep the hostname + $this->config[ 'hostname' ] = preg_replace('|.+?://|', '', $this->config[ 'hostname' ]); + + language() + ->addFilePath(str_replace('Handlers', '', __DIR__) . DIRECTORY_SEPARATOR) + ->loadFile('ftp'); + } + + // -------------------------------------------------------------------- + + /** + * Ftp::connect + * + * Connect to FTP server. + * + * @return bool Returns TRUE on success or FALSE on failure. + * @throws RuntimeException + */ + public function connect() + { + if (false === ($this->handle = @ftp_connect($this->config[ 'hostname' ], $this->config[ 'port' ]))) { + if ($this->debugMode === true) { + throw new RuntimeException('FTP_E_UNABLE_TO_CONNECT'); + } + + $this->addError(1, 'FTP_E_UNABLE_TO_CONNECT'); + + return false; + } + + if (false !== (@ftp_login($this->handle, $this->config[ 'username' ], $this->config[ 'password' ]))) { + if ($this->debugMode === true) { + throw new RuntimeException('FTP_E_UNABLE_TO_LOGIN'); + } + + $this->addError(2, 'FTP_E_UNABLE_TO_LOGIN'); + + return false; + } + + // Set passive mode if needed + if ($this->passiveMode === true) { + ftp_pasv($this->handle, true); + } + + return true; + } + + // -------------------------------------------------------------------- + + /** + * Ftp::download + * + * Download a file from a remote server to the local server + * + * @param string $remoteFilePath Remote file path. + * @param string $localFilePath Local destination file path. + * @param string $mode File transfer mode. + * + * @return bool Returns TRUE on success or FALSE on failure. + * @throws RuntimeException + */ + public function download($remoteFilePath, $localFilePath, $mode = 'auto') + { + if ( ! $this->isConnected()) { + return false; + } + + // Set the mode if not specified + if ($mode === 'auto') { + // Get the file extension so we can set the upload type + $ext = $this->getExtension($remoteFilePath); + $mode = $this->getTransferMode($ext); + } + + $mode = ($mode === 'ascii') ? FTP_ASCII : FTP_BINARY; + + $result = @ftp_get($this->handle, $localFilePath, $remoteFilePath, $mode); + + if ($result === false) { + if ($this->debugMode === true) { + throw new RuntimeException('FTP_E_UNABLE_TO_DOWNLOAD'); + } + + $this->addError(3, 'FTP_E_UNABLE_TO_DOWNLOAD'); + + return false; + } + + return true; + } + + // -------------------------------------------------------------------- + + /** + * Ftp::isConnected + * + * Validates the connection ID + * + * @return bool Returns TRUE on success or FALSE on failure. + * @throws RuntimeException + */ + protected function isConnected() + { + if ( ! is_resource($this->handle)) { + if ($this->debugMode === true) { + throw new RuntimeException('FTP_E_NO_CONNECTION'); + } + + $this->addError(4, 'FTP_E_NO_CONNECTION'); + + return false; + } + + return true; + } + + // -------------------------------------------------------------------- + + /** + * Ftp::getExtension + * + * Extract the file extension. + * + * @param string $filename String of filename to be extracted. + * + * @return string By default it's set into txt file extension. + */ + protected function getExtension($filename) + { + return (($dot = strrpos($filename, '.')) === false) + ? 'txt' + : substr($filename, $dot + 1); + } + + // -------------------------------------------------------------------- + + /** + * Ftp::getTransferMode + * + * Gets upload transfer mode. + * + * @param string $ext Filename extension. + * + * @return string By default it's set into ascii mode. + */ + protected function getTransferMode($ext) + { + return in_array( + $ext, + ['txt', 'text', 'php', 'phps', 'php4', 'js', 'css', 'htm', 'html', 'phtml', 'shtml', 'log', 'xml'], + true + ) + ? 'ascii' + : 'binary'; + } + + // -------------------------------------------------------------------- + + /** + * Ftp::rename + * + * Rename a file on ftp server. + * + * @param string $oldFilename Old filename. + * @param string $newFilename New filename. + * + * @return bool Returns TRUE on success or FALSE on failure. + * @throws RuntimeException + */ + public function rename($oldFilename, $newFilename) + { + if ( ! $this->isConnected()) { + return false; + } + + $result = @ftp_rename($this->handle, $oldFilename, $newFilename); + + if ($result === false) { + if ($this->debugMode === true) { + throw new RuntimeException('FTP_UNABLE_TO_RENAME'); + } + + $this->addError(5, 'FTP_UNABLE_TO_RENAME'); + + return false; + } + + return true; + } + + // -------------------------------------------------------------------- + + /** + * Ftp::moveFile + * + * Moves a file on the FTP server. + * + * @param string $oldRemoteFilePath Old file path on the FTP server. + * @param string $newRemoteFilePath New file path on the FTP server. + * + * @return bool Returns TRUE on success or FALSE on failure. + * @throws RuntimeException + */ + public function move($oldRemoteFilePath, $newRemoteFilePath) + { + if ( ! $this->isConnected()) { + return false; + } + + $result = @ftp_rename($this->handle, $oldRemoteFilePath, $newRemoteFilePath); + + if ($result === false) { + if ($this->debugMode === true) { + throw new RuntimeException('FTP_UNABLE_TO_MOVE'); + } + + $this->addError(6, 'FTP_UNABLE_TO_MOVE'); + + return false; + } + + return true; + } + + // -------------------------------------------------------------------- + + /** + * Ftp::deleteFile + * + * Deletes a file on the FTP server + * + * @param string $filePath Path to the file to be deleted. + * + * @return bool Returns TRUE on success or FALSE on failure. + * @throws RuntimeException + */ + public function deleteFile($filePath) + { + if ( ! $this->isConnected()) { + return false; + } + + $result = @ftp_delete($this->handle, $filePath); + + if ($result === false) { + if ($this->debugMode === true) { + throw new RuntimeException('FTP_E_UNABLE_TO_DELETE'); + } + + $this->addError(7, 'FTP_E_UNABLE_TO_DELETE'); + + return false; + } + + return true; + } + + // -------------------------------------------------------------------- + + /** + * Ftp::deleteDir + * + * Delete a folder and recursively delete everything (including sub-folders) + * contained within it on the FTP server. + * + * @param string $remotePath Path to the directory to be deleted on the FTP server. + * + * @return bool Returns TRUE on success or FALSE on failure. + * @throws RuntimeException + */ + public function deleteDir($remotePath) + { + if ( ! $this->isConnected()) { + return false; + } + + // Add a trailing slash to the file path if needed + $remotePath = preg_replace('/(.+?)\/*$/', '\\1/', $remotePath); + + $list = $this->getFiles($remotePath); + if ( ! empty($list)) { + for ($i = 0, $c = count($list); $i < $c; $i++) { + // If we can't delete the item it's probaly a directory, + // so we'll recursively call delete_dir() + if ( ! preg_match('#/\.\.?$#', $list[ $i ]) && ! @ftp_delete($this->handle, $list[ $i ])) { + $this->deleteDir($list[ $i ]); + } + } + } + + if (@ftp_rmdir($this->handle, $remotePath) === false) { + if ($this->debugMode === true) { + throw new RuntimeException('FTP_E_UNABLE_TO_DELETE_DIRECTORY'); + } + + $this->addError(8, 'FTP_E_UNABLE_TO_DELETE_DIRECTORY'); + + return false; + } + + return true; + } + + // -------------------------------------------------------------------- + + /** + * Ftp::getFiles + * + * FTP List files in the specified directory. + * + * @param string $remotePath Path to the remote directory. + * + * @return array|bool Returns array of files list or FALSE on failure. + * @throws RuntimeException + */ + public function getFiles($remotePath = '.') + { + return $this->isConnected() + ? ftp_nlist($this->handle, $remotePath) + : false; + } + + // -------------------------------------------------------------------- + + /** + * Ftp::mirror + * + * Read a directory and recreate it remotely. + * + * This function recursively reads a folder and everything it contains + * (including sub-folders) and creates a mirror via FTP based on it. + * Whatever the directory structure of the original file path will be + * recreated on the server. + * + * @param string $localPath Path to source with trailing slash + * @param string $remotePath Path to destination - include the base folder with trailing slash + * + * @return bool Returns TRUE on success or FALSE on failure. + * @throws RuntimeException + */ + public function mirror($localPath, $remotePath) + { + if ( ! $this->isConnected()) { + return false; + } + + // Open the local file path + if ($fp = @opendir($localPath)) { + // Attempt to open the remote file path and try to create it, if it doesn't exist + if ( ! $this->changeDir($remotePath, true) && ( ! $this->makeDir($remotePath) OR ! $this->changeDir( + $remotePath + )) + ) { + return false; + } + + // Recursively read the local directory + while (false !== ($file = readdir($fp))) { + if (is_dir($localPath . $file) && $file[ 0 ] !== '.') { + $this->mirror($localPath . $file . '/', $remotePath . $file . '/'); + } elseif ($file[ 0 ] !== '.') { + // Get the file extension so we can se the upload type + $ext = $this->getExtension($file); + $mode = $this->getTransferMode($ext); + + $this->upload($localPath . $file, $remotePath . $file, $mode); + } + } + + return true; + } + + return false; + } + + // -------------------------------------------------------------------- + + /** + * Ftp::changeDir + * + * The second parameter lets us momentarily turn off debugging so that + * this function can be used to test for the existence of a folder + * without throwing an error. There's no FTP equivalent to is_dir() + * so we do it by trying to change to a particular directory. + * Internally, this parameter is only used by the "mirror" function below. + * + * @param string $remotePath The remote directory path. + * @param bool $suppressDebug Suppress debug mode. + * + * @return bool Returns TRUE on success or FALSE on failure. + * @throws RuntimeException + */ + public function changeDir($remotePath, $suppressDebug = false) + { + if ( ! $this->isConnected()) { + return false; + } + + $result = @ftp_chdir($this->handle, $remotePath); + + if ($result === false) { + if ($this->debugMode === true AND $suppressDebug === false) { + throw new RuntimeException('FTP_E_UNABLE_TO_CHANGE_DIRECTORY'); + } + + $this->addError(9, 'FTP_E_UNABLE_TO_CHANGE_DIRECTORY'); + + return false; + } + + return true; + } + + // ------------------------------------------------------------------------ + + /** + * Ftp::makeDir + * + * Create a remote directory on the ftp server. + * + * @param string $remotePath The remote directory that will be created on ftp server. + * @param int $permissions The remote directory permissions. + * + * @return bool Returns TRUE on success or FALSE on failure. + * @throws RuntimeException + */ + public function makeDir($remotePath, $permissions = null) + { + if ($remotePath === '' OR ! $this->isConnected()) { + return false; + } + + $result = @ftp_mkdir($this->handle, $remotePath); + + if ($result === false) { + if ($this->debugMode === true) { + throw new RuntimeException('FTP_E_UNABLE_TO_MAKE_DIRECTORY'); + } + + $this->addError(10, 'FTP_E_UNABLE_TO_MAKE_DIRECTORY'); + + return false; + } + + // Set file permissions if needed + if ($permissions !== null) { + $this->setChmod($remotePath, (int)$permissions); + } + + return true; + } + + // -------------------------------------------------------------------- + + /** + * Ftp::setChmod + * + * Set remote file permissions. + * + * @param string $remotePath Path to the remote directory or file to be changed. + * @param int $mode Remote directory permissions mode. + * + * @return bool Returns TRUE on success or FALSE on failure. + * @throws RuntimeException + */ + public function setChmod($remotePath, $mode) + { + if ( ! $this->isConnected()) { + return false; + } + + if (@ftp_chmod($this->handle, $mode, $remotePath) === false) { + if ($this->debugMode === true) { + throw new RuntimeException('FTP_E_UNABLE_TO_CHMOD'); + } + + $this->addError(11, 'FTP_E_UNABLE_TO_CHMOD'); + + return false; + } + + return true; + } + + // -------------------------------------------------------------------- + + /** + * Ftp::upload + * + * Uploader a file to the ftp server. + * + * @param string $localFilePath Local source file path. + * @param string $remoteFilePath Remote destination file path. + * @param string $mode File transfer mode. + * @param int $permissions Remote file permissions. + * + * @return bool Returns TRUE on success or FALSE on failure. + * @throws RuntimeException + */ + public function upload($localFilePath, $remoteFilePath, $mode = 'auto', $permissions = null) + { + if ( ! $this->isConnected()) { + return false; + } + + if (is_file($localFilePath)) { + // Set the mode if not specified + if ($mode === 'auto') { + // Get the file extension so we can set the upload type + $ext = $this->getExtension($localFilePath); + $mode = $this->getTransferMode($ext); + } + + $mode = ($mode === 'ascii') ? FTP_ASCII : FTP_BINARY; + + $result = @ftp_put($this->handle, $remoteFilePath, $localFilePath, $mode); + + if ($result === false) { + if ($this->debugMode === true) { + throw new RuntimeException('FTP_E_UNABLE_TO_UPLOAD'); + } + + $this->addError(12, 'FTP_E_UNABLE_TO_UPLOAD'); + + return false; + } + + // Set file permissions if needed + if ($permissions !== null) { + $this->setChmod($remoteFilePath, (int)$permissions); + } + + return true; + } + + return false; + } + + // ------------------------------------------------------------------------ + + /** + * Ftp::close + * + * Close the current ftp connection. + * + * @return bool Returns TRUE on success or FALSE on failure. + * @throws RuntimeException + */ + public function close() + { + return $this->isConnected() + ? @ftp_close($this->handle) + : false; + } } \ No newline at end of file diff --git a/src/Handlers/Stream.php b/src/Handlers/Stream.php new file mode 100644 index 0000000..9ec02e0 --- /dev/null +++ b/src/Handlers/Stream.php @@ -0,0 +1,179 @@ +getRealPath())) { + $this->resource = fopen($file->getRealPath(), $mode); + } + } + + // ------------------------------------------------------------------------ + + /** + * Stream::setPointer + * + * @param int $point + * @return static + */ + public function setPointer($point) + { + $this->pointer = $point; + return $this; + } + + // ------------------------------------------------------------------------ + + /** + * Stream::getPointer + * + * @return int + */ + public function getPointer() + { + return $this->pointer; + } + + // ------------------------------------------------------------------------ + + /** + * Stream::getResource + * + * @return false|resource + */ + public function getResource() + { + return $this->resource; + } + + // ------------------------------------------------------------------------ + + /** + * Stream::forward + * + * @param int $length + */ + public function forward($length) + { + $this->pointer += $length; + fseek($this->resource, $this->pointer); + } + + //------------------------------------------------------- + + /** + * Stream::rewind + * + * @param int $length + */ + public function rewind($length) + { + $this->pointer -= $length; + fseek($this->resource, $this->pointer); + } + + //------------------------------------------------------- + + /** + * Stream::readByteOfData + * + * @param $length + * @return false|string + */ + public function readByteOfData($length) + { + $data = fread($this->resource, $length); + $this->pointer += $length; + return $data; + } + + //------------------------------------------------------- + + /** + * Stream::readByteInteger + * + * @return int + */ + public function readByteInteger() + { + $data = fread($this->resource, 1); + $this->pointer++; + return ord($data); + } + + //------------------------------------------------------- + + /** + * Stream::isValidByte + * + * @param string $byte + * @return bool + */ + public function isValidByte($byte) + { + if (fgetc($this->resource) == chr($byte)) { + fseek($this->resource, $this->pointer); + return true; + } else { + fseek($this->resource, $this->pointer); + return false; + } + } + + //------------------------------------------------------- + + /** + * Stream::isEndOfFile + * + * @return bool + */ + public function isEndOfFile() + { + if (fgetc($this->resource) === false) { + return true; + } else { + fseek($this->resource, $this->pointer); + return false; + } + } + //------------------------------------------------------- + + /** + * Stream::close + */ + public function close() + { + if(is_resource($this->resource)) { + fclose($this->resource); + } + } +} \ No newline at end of file