Вход Регистрация
Файл: DESURE-dcms-f12de01ac63e/sys/plugins/classes/files_file.class.php
Строк: 463
<?php

/**
 * Работа с файлом загруз-центра
 * @property int id Идентификатор файла в базе
 * @property string name Имя файла на сервере
 * @property string runame Локализованное имя файла
 * @property int group_show индекс группы пользователя, которому разрешено видеть файл
 * @property string path_dir_abs Абсолютный путь к папке
 * @property string path_file_abs Абсолютный путь к файлу
 * @property string path_dir_rel Относительный путь к папке
 * @property string path_file_rel относительный путь к файлу
 * @property float rating рейтинг файла
 * @property int rating_count кол-во голосов
 * @property int properties_auto_comlete флаг: Свойства автоматически получены
 * @property int screens_auto_comlete флаг: Скриншоты автоматически получены
 * @property string description Описание файла
 * @property int size Размер файла в байтах
 * @property int time_add Дата добавления файла (TIMESTAMP)
 * @property int time_create Дата создания файла (TIMESTAMP)
 * @property int comments Кол-во комментариев
 * @property int group_edit Индекс группы пользователя, которой разрешено изменять параметры файла
 * @property int id_user Идентификатор пользователя, добавившего файл
 */
class files_file
{

    protected 
$_data = array(); // информация о файле
    
protected $_screens = array(); // скриншоты (имена файлов)
    
protected $_need_save false// необходимость пересохранения сведений о файле
    
var $ratings = array();

    
/**
     * files_file::__construct()
     *
     * @param string $path_dir_abs
     * @param string $filename
     */
    
function __construct($path_dir_abs$filename) {
        
$this->ratings = array(
            -
=> __('Ужасный файл'),
            -
=> __('Плохой файл'),
            
=> __('Без оценки'),
            
=> __('Хороший файл'),
            
=> __('Отличный файл')
        );

        
$this->_data['id'] = 0;
        
$this->_data['runame'] = convert::to_utf8($filename); // имя на русском (чтобы небыло пустым)
        
$this->_data['id_user'] = 0// создатель файла
        
$this->_data['downloads'] = 0// кол-во скачиваний файла
        
$this->_data['description'] = ''// описание файла (задается вручную)
        
$this->_data['description_small'] = ''// короткое описание файла (задается вручную)
        
$this->_data['rating'] = 0// рейтинг файла
        
$this->_data['rating_count'] = 0// кол-во проголосовавших
        
$this->_data['comments'] = 0// кол-во комментариев
        
$this->_data['meta_description'] = '';
        
$this->_data['meta_keywords'] = '';

        if (
$cfg_ini ini::read($path_dir_abs '/.' $filename '.ini'true)) {
            
// загружаем конфиг
            
$this->_data array_merge($this->_data, (array)@$cfg_ini['CONFIG']);
            
$this->_screens array_merge($this->_screens, (array)@$cfg_ini['SCREENS']);
        } else {
            
$dir = new files($path_dir_abs);
            
$this->_data['group_show'] = $dir->group_show// группа, которой доступен файл
            
$this->_data['group_edit'] = max($dir->group_write2); // группа, которая имеет право на изменение параметров файла
            // если конфиг не загрузился, то предполагаем что файл грузился не средствами движка,
            // поэтому задаем ему время добавления
            
$this->_data['time_add'] = TIME// дата добавления файла
            
$this->_need_save true// обязательно сохраняем сведения о файле
        
}
        
$this->_data['name'] = $filename;

        
// расширение файла
        
$pinfo pathinfo(strtolower($filename));
        
$this->_data['ext'] = $pinfo['extension'];

        
$this->_setPathes($path_dir_abs);
        
// получение дополнительных сведений о файле
        
$this->_getPropertiesAuto();

        if (!
$this->id)
            
$this->_baseAdd();
    }

    
/**
     * переименование файла
     * @param string $runame
     * @param string|bool $name
     * @return boolean
     */
    
public function rename($runame$name false)
    {
        if (
$this->name{0} == '.')
            return 
false;

        if (
$name && $name{0} == '.')
            return 
false;

        if (
$name && file_exists($this->path_dir_abs '/' $name))
            return 
false;

        if (
$name && @rename($this->path_file_abs$this->path_dir_abs '/' $name)) {
            
// переименовываем скрины
            
foreach ($this->_screens as $scr_key => $scr_file) {
                if (@
rename($this->path_dir_abs '/' $scr_file$this->path_dir_abs '/.' $name '.' $scr_key '.jpg'))
                    
$this->_screens[$scr_key] = '.' $name '.' $scr_key '.jpg';
            }
            
// переименовываем конфиг
            
@rename($this->path_dir_abs '/.' $this->name '.ini'$this->path_dir_abs '/.' $name '.ini');
            
$this->name $name;
        }

        
$this->runame $runame;
        return 
true;
    }

    
/**
     * Перемещение файла
     * @global user $user
     * @param string $path_dir_abs
     * @return boolean
     */
    
public function moveTo($path_dir_abs)
    {
        global 
$user;

        
$dir = new files($path_dir_abs);

        if (
$dir->group_show $user->group || $dir->group_write $user->group) {
            
// если нет прав на просмотр или запись в папку
            
return false;
        }

        if (@
rename($this->path_file_abs$dir->path_abs '/' $this->name)) {
            
// переименовываем скрины
            
foreach ($this->_screens as $scr_key => $scr_file) {
                if (@
rename($this->path_dir_abs '/' $scr_file$dir->path_abs '/.' $this->name '.' $scr_key '.jpg'))
                    
$this->_screens[$scr_key] = '.' $this->name '.' $scr_key '.jpg';
            }
            
// переименовываем конфиг
            
@rename($this->path_dir_abs '/.' $this->name '.ini'$dir->path_abs '/.' $this->name '.ini');
            
$this->path_dir_abs $dir->path_abs;
            return 
true;
        }
        return 
false;
    }

    
/**
     * Список доступных ключей (для сортировки)
     * @return array
     */
    
public function getKeys()
    {
        
$keys = array();
        if (!empty(
$this->_data['time_create']))
            
$keys['time_create:desc'] = __('Время создания');
        if (!empty(
$this->_data['downloads']))
            
$keys['downloads:desc'] = __('Кол-во скачиваний');
        if (!empty(
$this->_data['comments']))
            
$keys['comments:desc'] = __('Кол-во комментариев');
        if (!empty(
$this->_data['id_user']))
            
$keys['id_user:desc'] = __('Автор');
        if (!empty(
$this->_data['rating']))
            
$keys['rating:desc'] = __('Рейтинг');
        if (!empty(
$this->_data['title']))
            
$keys['title:asc'] = __('Заголовок');
        if (!empty(
$this->_data['frames']))
            
$keys['frames:desc'] = __('Кол-во кадров');
        if (!empty(
$this->_data['width']))
            
$keys['width:desc'] = __('Разрешение');
        if (!empty(
$this->_data['video_codec']))
            
$keys['video_codec:asc'] = __('Видео кодек');
        if (!empty(
$this->_data['audio_codec']))
            
$keys['audio_codec:asc'] = __('Аудио кодек');
        if (!empty(
$this->_data['playtime_seconds']))
            
$keys['playtime_seconds:desc'] = __('Продолжительность');
        if (!empty(
$this->_data['artist']))
            
$keys['artist:asc'] = __('Исполнители');
        if (!empty(
$this->_data['band']))
            
$keys['band:asc'] = __('Группа');
        if (!empty(
$this->_data['album']))
            
$keys['album:asc'] = __('Альбом');
        if (!empty(
$this->_data['genre']))
            
$keys['genre:asc'] = __('Жанр');
        if (!empty(
$this->_data['track_number']))
            
$keys['track_number:asc'] = __('Номер трека');
        if (!empty(
$this->_data['vendor']))
            
$keys['vendor:asc'] = __('Производитель');

        return 
$keys;
    }

    
/**
     * Удаление данного файла и всей дополнительной информации к нему.
     * @return boolean
     */
    
public function delete()
    {
        if (!
file_exists($this->path_file_abs) || @unlink($this->path_file_abs)) {
            
// удаляем скрины
            
if ($this->_screens) {
                foreach (
$this->_screens as $num => $scr_file) {
                    
$this->screenDelete($num);
                }
            }

            
// удаляем конфиг
            
@unlink($this->path_dir_abs '/.' $this->name '.ini');

            
$this->_baseDelete();
            
$dir = new files($this->path_dir_abs);
            
$dir->cacheClear();
            
$this->_need_save false;
            
$this->__destruct();
            return 
true;
        }
        return 
false;
    }

    
/**
     * проверяем, можно ли голосовать
     * @global user $user
     * @param bool|int $set
     * @return int
     */
    
public function rating_my($set false)
    {
        global 
$user;
        
$q db::me()->prepare("SELECT `rating` FROM `files_rating` WHERE `id_file` = ? AND `id_user` = ?");
        
$q->execute(Array($this->id$user->id));
        if (!
$my_rating $q->fetch()) {
            
$my_rating 0;
        }

        if (
$set !== false && isset($this->ratings[$set])) {
            if (
$set && $my_rating) {
                
// Изменяем запись
                
$my_rating = (int) $set;
                
$res db::me()->prepare("UPDATE `files_rating` SET `rating` = ?, `time` = ? WHERE `id_file` = ? AND `id_user` = ? LIMIT 1");
                
$res->execute(Array($my_ratingTIME$this->id$user->id));
            } elseif (
$set) {
                
// Вносим запись
                
$my_rating = (int) $set;
                
$res db::me()->prepare("INSERT INTO `files_rating` (`id_file`, `id_user`, `time`, `rating`) VALUES (?, ?, ?, ?)");
                
$res->execute(Array($this->id$this->idTIME$my_rating));
            } elseif (
$my_rating) {
                
// Удаляем запись
                
$my_rating 0;
                
$res db::me()->prepare("DELETE FROM `files_rating` WHERE `id_file` = ? AND `id_user` = ?");
                
$res->execute(Array($this->id$user->id));
            }

            
$this->rating_update();
        }

        return 
$my_rating;
    }

    
/**
     * Обновление рейтинга
     */
    
public function rating_update() {
        
$q db::me()->prepare("SELECT AVG(`rating`) AS `rating`, COUNT(`id_user`) AS `rating_count` FROM `files_rating` WHERE `id_file` = ?");
        
$q->execute(Array($this->_data['id']));
        
$data $q->fetch();
        
$this->rating $data['rating'];
        
$this->rating_count $data['rating_count'];
    }

    
/**
     * Извлечение дополнительных сведений о файле
     * @return boolean
     */
    
protected function _getPropertiesAuto()
    {
        if (
$this->properties_auto_comlete)
            return;
        if (
$desc files_types::getPropertiesType($this->path_file_abs)) {
            if (@
function_exists('set_time_limit')) {
                @
set_time_limit(30);
            }
            
$propert "files_properties_$desc";
            
$prop_obj = new $propert($this->path_file_abs);
            if (
$prop $prop_obj->getProperties()) {
                
$this->_data array_merge((array)$prop$this->_data);
            }
        }
        
$this->properties_auto_comlete 1;
    }

    
/**
     * Кол-во скриншотов
     * @return int
     */
    
public function getScreensCount()
    {
        
$this->_createScreensAuto();
        return 
count($this->_screens);
    }

    
/**
     * Получение скриншота определенного размера (путь в браузере)
     * @param int $img_max_width
     * @param int $num
     * @return string|boolean
     */
    
public function getScreen($img_max_width$num 0)
    {
        
$this->_createScreensAuto();
        if (!empty(
$this->_screens[$num])) {
            
$screen_path_rel '/sys/tmp/public.' md5($this->path_file_rel) . '.time_add' $this->time_add '.num' $num '.width' $img_max_width '.jpg';

            if (
file_exists($screen_path_rel))
                return 
$screen_path_rel;
            if (!
$img = @imagecreatefromjpeg($this->path_dir_abs '/' $this->_screens[$num]))
                return 
false;
            
$img_screen imaging::to_screen($img$img_max_width);

            if (
$img_max_width 48)
                
imaging::add_copyright($img_screen);

            if (
imagejpeg($img_screen$screen_path_rel85))
                return 
$screen_path_rel;
        }
        return 
false;
    }

    
/**
     * Добавление скриншота
     * @param resource $img
     * @return boolean
     */
    
public function screenAdd($img)
    {
        
sort($this->_screens);
        
$key count($this->_screens);
        
$scr '.' $this->name '.' $key '.jpg';
        if (!@
imagejpeg($img$this->path_dir_abs '/' $scr85))
            return 
false;
        
$this->_screens[$key] = $scr;
        
$this->_need_save true;
        return 
true;
    }

    
/**
     * Удаление скриншота
     * @param int $num
     * @return boolean
     */
    
public function screenDelete($num)
    {
        if (empty(
$this->_screens[$num]))
            return 
false;

        if (@
unlink($this->path_dir_abs '/' $this->_screens[$num]) || !file_exists($this->path_dir_abs '/' $this->_screens[$num])) {
            
// удаление уменьшенных копий скриншотов
            
$screen_path_tmp = (array)glob('/sys/tmp/public.' md5($this->path_file_rel) . '.num' $num '.width*.jpg');
            foreach (
$screen_path_tmp as $path_to_delete) {
                @
unlink($path_to_delete);
            }

            unset(
$this->_screens[$num]);
            
sort($this->_screens);
            
$this->_need_save true;
            return 
true;
        }
        return 
false;
    }

    
/**
     * Удаление скриншотов и установка отметки, что автоматически скриншоты еще не генерировались
     */
    
public function screensReset()
    {
        
$count $this->getScreensCount();
        for (
$i 0$i $count$i++) {
            
$this->screenDelete($i);
        }
        
$this->screens_auto_comlete 0;
    }

    
/**
     * Автоматическое создание скриншотов
     * @return boolean
     */
    
protected function _createScreensAuto()
    {
        if (
$this->screens_auto_comlete)
            return;
        if (
$screen files_types::getScreenType($this->path_file_abs)) {
            
$screener "files_screen_$screen";
            
$scr_obj = new $screener($this->path_file_abs);

            if (@
function_exists('set_time_limit')) {
                @
set_time_limit(30);
            }
            if (
$imgs $scr_obj->getScreen()) {
                
$imgs = (array)$imgs;

                foreach (
$imgs as $img) {
                    
$this->screenAdd($img);
                }
            }
        }
        
$this->screens_auto_comlete 1;
    }

    
/**
     * Название иконки по типу файла
     * @return string
     */
    
public function icon()
    {
        return 
files_types::getIconType($this->path_file_abs);
    }

    
/**
     * Ссылка на уменьшенное изображение
     * @param int $size макс. ширина в пикселях
     * @param int $num
     * @return string
     */
    
public function image($size 48$num 0)
    {
        if (
$screen $this->getScreen($size$num)) {
            return 
$screen;
        }
        return 
false;
    }

    
/**
     * Установка путей
     * @param string $path_dir_abs
     */
    
protected function _setPathes($path_dir_abs)
    {
        
// полный путь к папке
        
$this->path_dir_abs filesystem::unixpath($path_dir_abs);
        
// полный путь к файлу
        
$this->path_file_abs $this->path_dir_abs '/' $this->name;
        
// относительный путь к папке
        
$this->path_dir_rel str_replace(filesystem::unixpath(FILES), ''$this->path_dir_abs);
        
// относительный путь к файлу
        
$this->path_file_rel $this->path_dir_rel '/' $this->name;
    }

    
/**
     * Заносим сведения о файле в базу
     * @return boolean
     */
    
protected function _baseAdd()
    {
        if (
$this->id)
            return 
false;
        if (
$this->name{0} == '.')
            return 
false;

        
$res db::me()->prepare("INSERT INTO `files_cache` (`path_file_rel`, `time_add`, `group_show`, `runame`)
VALUES (?, ?, ?, ?)"
);
        
$res->execute(Array(convert::to_utf8($this->path_file_rel), intval($this->time_add), intval($this->group_show), $this->runame));
        return (bool) 
$this->id db::me()->lastInsertId();
    }

    
/**
     * обновляем сведения о файле в базе данных
     */
    
protected function _baseUpdate() {
        
$res db::me()->prepare("UPDATE `files_cache`
SET `path_file_rel` = ?,
`time_add` = ?,
`group_show` = ?,
`runame` = ?
WHERE `id` = ? LIMIT 1"
);
        
$res->execute(Array(convert::to_utf8($this->path_file_rel), intval($this->time_add), intval($this->group_show), $this->runameintval($this->id)));
    }

    
/**
     * Удаляем сведения о файле из базы данных
     * @return boolean
     */
    
protected function _baseDelete()
    {
        
// удаление файла из кэша базы
        
$res=db::me()->prepare("DELETE FROM `files_cache` WHERE `id` = ? LIMIT 1");
        
$res->execute(Array(intval($this->id)));
        
// удаление комментов к файлу
        
$res=db::me()->prepare("DELETE FROM `files_comments` WHERE `id_file` = ?");
        
$res->execute(Array(intval($this->id)));
        
// удаление рейтингов файла
        
$res=db::me()->prepare("DELETE FROM `files_rating` WHERE `id_file` = ?");
        
$res->execute(Array(intval($this->id)));
        return 
true;
    }

    
/**
     * Возвращение поти в файлу для ссылки
     * @return string
     */
    
public function getPath()
    {
        
$path_rel preg_split('#/+#'$this->path_dir_rel);
        foreach (
$path_rel as $key => $value) {
            
$path_rel[$key] = urlencode($value);
        }
        return 
implode('/'$path_rel) . '/' urlencode($this->name);
    }

    
/**
     * размер файла в байтах
     * @return integer
     */
    
protected function _getSize()
    {
        
$size = @filesize($this->path_file_abs);
        return 
$this->size $size;
    }

    
/**
     * Дата и время создания файла в формате UNIXTIMESTAMP
     * @return integer
     */
    
protected function _getTimeCreate()
    {
        
$time = @filemtime($this->path_file_abs);
        return 
$this->time_create $time;
    }

    function 
__get($n)
    {
        global 
$dcms;
        switch (
$n) {
            case 
'rating_name':
                return 
$this->ratings[(int)round($this->rating)];
            case 
'description_small':
                return empty(
$this->_data[$n]) ? text::substr($this->description$dcms->browser_type == 'full' 512 256) : $this->_data[$n];
            case 
'time_create':
                return isset(
$this->_data[$n]) ? $this->_data[$n] : $this->_getTimeCreate();
            case 
'size':
                return isset(
$this->_data[$n]) ? $this->_data[$n] : $this->_getSize();
            default:
                return isset(
$this->_data[$n]) ? $this->_data[$n] : false;
        }
    }

    function 
__set($n$v)
    {
        if (!
is_scalar($n) || !is_scalar($v))
            return;

        if (
array_key_exists($n$this->_data) && $this->_data[$n] == $v)
            return;

        if (
$n == 'path_dir_abs') {
            
$dir_old = new files($this->path_dir_abs);
            
$dir_old->cacheClear();
        }

        
$this->_data[$n] = $v;
        
$this->_need_save true;

        if (
in_array($n, array('screens_auto_comlete''properties_auto_comlete''path_dir_abs'))) {
            
$dir_new = new files($this->path_dir_abs);
            
$dir_new->cacheClear();
        }

        if (
$n == 'path_dir_abs') {
            
$this->_setPathes($this->path_dir_abs);
        }

        if (
in_array($n, array('group_show''time_add''path_file_rel''runame')))
            
$this->_baseUpdate();
    }

    
/**
     * Сохранение информации о файле
     */
    
public function save_data()
    {
        if (
$this->name{0} !== '.') {
            
ini::save($this->path_dir_abs '/.' $this->name '.ini', array('CONFIG' => $this->_data'SCREENS' => $this->_screens), true);
        }
    }

    function 
__destruct()
    {
        if (
$this->_need_save) {
            
$this->save_data();
        }
    }

}
Онлайн: 1
Реклама