samsonos/php_core

View on GitHub
src/File.php

Summary

Maintainability
C
1 day
Test Coverage
<?php
namespace samson\core;

// TODO: Should separated to external module

/**
 * Общие методы для работы с файлами и каталогами
 * @author Vitaly Iegorov <vitalyiegorov@gmail.com>
 */
class File
{
    /**
     * Коллекция связей между MIME-type и расширениями файлов
     * @var array
     */
    public static $MIMEExtension = array
    (
        'text/css' => 'css',
        'application/x-font-woff' => 'woff',
        'application/x-javascript' => 'js',
        'text/html;charset=utf-8' => 'htm',
        'text/x-component' => 'htc',
        'image/jpeg' => 'jpg',
        'image/pjpeg' => 'jpg',
        'image/png' => 'png',
        'image/x-png' => 'png',
        'image/jpg' => 'jpg',
        'image/gif' => 'gif',
        'text/plain' => 'txt',
        'application/pdf' => 'pdf',
        'application/zip' => 'zip',
        'application/rtf' => 'rtf',
        'application/msword' => 'doc',
        'application/msexcel' => 'xls',
        'application/vnd.ms-excel' => 'xls',
        'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => 'xlsx',
        'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => 'docx',
        'application/octet-stream' => 'sql',
        'audio/mpeg' => 'mp3'
    );

    /**
     * Коллекция связей между расширениями файлов и их MIME-type
     * @var array
     */
    public static $ExtensionMIME = array();

    /**
     * Коллекция расширений файлов которые являются картинками
     * @var array
     */
    public static $ImageExtension = array
    (
        'jpg' => 'jpg',
        'jpeg' => 'jpeg',
        'png' => 'png',
        'jpg' => 'jpg',
        'gif' => 'gif'
    );

    /**
     * Проверить существует ли файл по указанному пути
     *
     * @param string $path Путь к файлу
     * @param string $file Имя файла для поиска
     */
    public static function find($path, $file)
    {
        return file_exists($path . '/' . $file);
    }

    /**
     * Скопировать файлы и папки используя рекурсивный перебор
     *
     * @param string $path Путь к источнику для копирования
     * @param string $dest Путь к месту куда необходимо выполнить копирование
     */
    public static function copy($path, $dest)
    {
        // Если это папка
        if (is_dir($path)) {
            // Создадим папку в том месте куда нужно копировать, если её там нет
            if (!file_exists($dest)) mkdir($dest, 0755, TRUE);

            // Получим содержание текущей папки
            $files = scandir($path);

            // Получим количетсво файлов в папке
            $files_count = sizeof($files);

            // Переберем полученные файлы
            for ($i = 2; $i < $files_count; $i++) {
                // Получим имя текущего файла
                $file = &$files[$i];

                // Получим полный путь к файлу источнику
                $source_path = $path . '/' . $file;

                // Получим полный путь к новому файлу
                $dest_path = $dest . '/' . $file;

                // Углубимся в рекурсию
                self::copy($source_path, $dest_path);
            }

            return TRUE;
        } // Просто скопируем файл
        else if (is_file($path)) {
            // Если передана папка как новый файл - получим имя файла
            if (is_dir($dest)) $dest .= pathinfo($path, PATHINFO_FILENAME) . '.' . pathinfo($path, PATHINFO_EXTENSION);

            return copy($path, $dest);
        } // Выходим
        else return FALSE;
    }

    /**
     * Очистить путь
     * Если передан путь к папке то очистим все её файлы(содержимое)
     * Если передан путь к файлу то удали его
     *
     * @param string $path          Путь к удаляемому ресурсу
     * @param array  $type          Collection of file extensions for ignoring
     * @param array  $ignoreFolders Collection of folders for ignoring
     *
     * @return boolean / FALSE
     */
    public static function clear($path, $type = NULL, $ignoreFolders = array())
    {
        // Если передан путь к папке то удалим все файлы в ней
        if (is_dir($path)) {
            $files = array();
            foreach (self::dir($path, $type, '', $files, null, 0, $ignoreFolders) as $file) {
                unlink($file);
            }

            return TRUE;
        } // Если передан путь к файлу то просто удалим его
        else if (file_exists($path)) {
            unlink($path);
            return TRUE;
        }

        return FALSE;
    }

    /**
     * Получить список файлов каталога
     *
     * @param string  $path      Путь к каталогу
     * @param string  $type      Фильтр для типа собираемых файлов
     * @param array   $result    Результат работі рекурсивной функции
     * @param string  $modifier  Модификатор пути к файлам для изменения их пути
     * @param string  $max_level Максимальная глубина работы метода
     * @param integer $level     Текщий уровень рекурсии
     * @param array   $restrict  Коллекция папок которые необходимо пропускать
     *
     * @return array Коллекция файлов в каталоге
     */
    public static function dir($path, $type = null, $modifier = '', & $result = array(), $max_level = NULL, $level = 0, $restrict = array('.git', '.svn', '.hg', '.settings'))
    {
        // Если установлено ограничение на глубину - выйдем
        if (isset($max_level) && $level > $max_level) return $result;

        // If type filter is passed make it array anyway
        if (isset($type) && !is_array($type)) {
            $type = array($type);
        }

        // Откроем папку
        if (file_exists($path) && $handle = opendir($path)) {
            /* Именно этот способ чтения элементов каталога является правильным. */
            while (false !== ($entry = readdir($handle))) {
                // Ignore root paths
                if ($entry == '..' || $entry == '.') {
                    continue;
                }

                // Build full REAL path to entry
                $full_path = realpath($path . '/' . $entry);

                if (is_file($full_path)) {
                    // Check file type if ty filter is passed
                    if (!isset($type) || in_array(pathinfo($full_path, PATHINFO_EXTENSION), $type)) {
                        $result[] = normalizepath($modifier . $full_path);
                    }
                } else if (is_dir($full_path)) {
                    // Define if current path is not restricted
                    $ignored = false;
                    // Iterate all restrictions
                    foreach ($restrict as $ignore) {
                        // Try to find ignored path pattern in full path and store it to ignored flag
                        if (($ignored = ($ignore == $full_path)) !== false) {
                            // This is ignored path - break, ignored now is false(0)
                            break;
                        }
                    }

                    // If this path is not restricted
                    if ($ignored === false) {
                        // Go deeper in recursion
                        self::dir($full_path, $type, $modifier, $result, $max_level, ++$level, $restrict);
                    }
                }
            }

            // Закроем чтение папки
            closedir($handle);
        }
        //else return e( 'Ошибка открытия папки(##)', E_SAMSON_CORE_ERROR, array( $path ) );

        // Сортируем
        if (sizeof($result)) sort($result);

        // Соберем массив в строку
        return $result;
    }

    /**
     * Create folder, method use recursive approach for creating if
     * "folder/folder/.." is passed.
     *
     * @param string $path  Folder path
     * @param string $group Folder group(www-data)
     * @param int    $mode  Folder mode(0775)
     *
     * @return int 1 - success, 0 - folder exists, -1 - errors
     */
    public static function mkdir($path, $group = 'www-data', $mode = 0775)
    {
        // If folder does not exists
        if (!file_exists($path)) {
            // Create folder with correct mode
            if (mkdir($path, $mode, true)) {
                // Change folder group
                @chgrp($path, $group);

                return true;
            } else {
                return -1;
            }
        }

        // Folder already exists
        return false;
    }

    /**
     * Определить расширение файла по его MIME типу
     *
     * @param string $mime_type MIME тип файла
     *
     * @return string Расширение файла
     */
    public static function getExtension($mime_type)
    {
        // Обработаем тип получаемого файла и вернем его расширение если файл поддерживается
        if (isset(self::$MIMEExtension[$mime_type])) return self::$MIMEExtension[$mime_type];

        // Ничего не вышло =(
        return FALSE;
    }

    /**
     * Определить MIME тип файла по его расширению
     *
     * @param string $path Путь к файлу или его имя
     *
     * @return string MIME тип файла
     */
    public static function getMIME($path)
    {
        // Получим расширение файла
        $file_ext = pathinfo($path, PATHINFO_EXTENSION);

        // Обработаем тип получаемого файла и вернем его расширение если файл поддерживается
        if (isset(self::$ExtensionMIME[$file_ext])) return self::$ExtensionMIME[$file_ext];

        // Ничего не вышло =(
        return 'application/octet-stream';
    }

    /**
     * Определить является ли указанный файл картинкой
     *
     * @param string $path Путь к файлу или его имя
     *
     * @return boolean Является ли данный файл картинкой
     */
    public static function isImage($path)
    {
        // Получим расширение файла - всегда берем первые 3 символа
        $file_ext = trim(substr(pathinfo($path, PATHINFO_EXTENSION), 0, 3));

        // Проверим является ли расширение файла картинкой
        return isset(self::$ImageExtension[$file_ext]);
    }
}

// Сформируем обратный массив связей между расширением файла и его MIME-type
File::$ExtensionMIME = array_flip( File::$MIMEExtension );