Загрузка файлов

Сделал на основе решения загрузки картинок решение, которое позволяет загружать файлы. Все довольно просто.

Создаем файл include/ajax/uploadFile.php и в нем пишем следующее содержимое:
<?php
/**
 * Загрузка файлов
 */

set_include_path(get_include_path().PATH_SEPARATOR.dirname(dirname(dirname(__FILE__))));
chdir(dirname(dirname(dirname(__FILE__))));
require_once("./config/config.ajax.php");

$fileTypes = array("zip", "rar");
$aForm=@$_REQUEST['value'];
$bStateError=true;
$sText='';
if ($oEngine->User_IsAuthorization()) {
	$sFile=null;
	$oUserCurrent=$oEngine->User_GetUserCurrent();
	
	if (is_uploaded_file($_FILES['usr_file']['tmp_name'])) {
		
		if(!($ext = strtolower(substr($_FILES['usr_file']['name'], (strrpos($_FILES['usr_file']['name'], ".") + 1))))) {
			$sText = 'Не удалось определить тип файла...';
		} elseif(!in_array($ext, $fileTypes)) {
			$sText = 'Для загрузки можно использовать только файлы следующих типов: ' . implode(', ', $fileTypes);
		} else {
			
			$usr_file = $_FILES['usr_file']['tmp_name'];
			$sDirSave=DIR_UPLOADS_FILES.'/'.$oUserCurrent->getId();
			$sFullPath=DIR_SERVER_ROOT . $sDirSave;
			
			if (!is_dir($sFullPath)) {
				mkdir($sFullPath);
				chmod($sFullPath, 0755);
			}
			
			$sFileNameNew = func_generator();
			
			$sFullFilePath = $sFullPath . '/' . $sFileNameNew . '.' . $ext;
			
			$sFile=$sDirSave.'/'.$sFileNameNew . '.' . $ext;
			
			if (move_uploaded_file($usr_file, $sFullFilePath)) {
				
				chmod($sFullFilePath, 0644);
				
			} else {
				$sText = 'Не удалось загрузить файл.';
			}
			
		}
		
		if (!is_null($sFile)) {
			$bStateError = false;
			$alt = (isset($_REQUEST['title']) and mb_strlen(trim($_REQUEST['title'], 'UTF-8'))) ? $alt = $_REQUEST['title'] : false;
			$sText = '<a href="'.$sFile.'">' . (($alt!=false) ? $alt : 'Файл для скачивания') . '</a>';
		}
		
	} else {
		$sText = 'Что-то не так...';
	}
}

$GLOBALS['_RESULT'] = array(
"bStateError"     => $bStateError,
"sText"   => $sText,
);

?>
<pre>
<b>Request method:</b> <?=$_SERVER['REQUEST_METHOD'] . "\n"?>
<b>Loader used:</b> <?=$JsHttpRequest->LOADER . "\n"?>
<b>_REQUEST:</b> <?=print_r($_REQUEST, 1)?>
</pre>


В файле main.js добавляем:

function ajaxUploadFile(value, sToLoad)
{
    var req = new JsHttpRequest();    
    req.onreadystatechange = function() {
        if (req.readyState == 4) {         
            document.getElementById('debug').innerHTML = req.responseText;  
            closeWindowStatus();         
            if (req.responseJS.bStateError) {
            	showWindowStatus(req.responseJS.sText);
            } else {   
            	voidPutTag(sToLoad,req.responseJS.sText);            	
            }
        }
    }    
    closeWindow('window_load_file');
    showWindowStatus('Загрузка файла...');
    req.open(null, DIR_WEB_ROOT+'/include/ajax/uploadFile.php', true);    
    req.send( { value: value } );
}


И соответственно в шаблон actions/ActionTopic/add.tpl добавляем:
<div id="window_load_file" style="display: none;">
	<form method="POST" action="" enctype="multipart/form-data" id="form_upload_file" >
	<table width="500px"  border="0">
		<tr>
			<th align="center" colspan="2">Вставка файла</th>			
		</tr>
		<tr>
			<td align="right">Файл:</td>
			<td width="100%"><input type="file" name="usr_file" style="width: 100%;" value=""></td>
		</tr>
		<tr>
			<td align="right">Текст ссылки:</td>
			<td><input type="text" name="title" style="width: 100%;"></td>
		</tr>
		<tr>
			<td></td>
			<td>
				<input type="button" value="Загрузить" onclick="ajaxUploadFile(document.getElementById('form_upload_file'),'topic_text');">
				<input type="button" value="Отмена" onclick="closeWindow('window_load_file'); return false;">
			</td>
		</tr>
	</table>
	</form>
</div>


В файле config.php (строка 40) добавляем:

define('DIR_UPLOADS_FILES',DIR_UPLOADS.'/files');


И еще необходимо создать в папке uploads подпапку files.

Вот и все.

С помощью массива $fileTypes вы можете определить доступные типы файлов.

Надеюсь, что со стилями сами разберетесь, так как у меня шаблоны другие совсем.

48 комментариев

avatar
Спасибо. Как раз очень необходимая примочка к движку.
avatar
возникли две проблемы:
1) окно вставки файла получается не как окно вставки картинки (всплывающее) а просто в странице.
2) после добавления файла появляется аяксовая «загрузка файла» и ничего не происходит. такое ощущение, что не подхватывается файл uploadFile.php
avatar
1) Потому и примечание «Надеюсь, что со стилями сами разберетесь, так как у меня шаблоны другие совсем.»
2) С этим подробнее, если можно. Это сразу после нажатия происходит и не выводится никаких сообщений? Какой файл пытаетесь скормить (размер, расширение)?
avatar
>>Это сразу после нажатия происходит и не выводится никаких сообщений?
именно… а файлы без разницы, пробовал exe, zip, jpg.
avatar
Ага… сейчас попробую выяснить… может я чего не выписал…
avatar
А папка files есть? Создалось ли в ней что-нибудь?
avatar

все, я нашел косяк))) делал ночью, спать сильно хотелось, попытался сделать методом копипаста, а в начале файла uploadFile.php у вас пропущена магическая <?php> :) Огромное спасибо за мануал, пойду ковырять стили.
avatar
Ааа… и точно. А сейчас все работает как надо?
avatar
да, все отлично. осталось найти только подходящую иконку для редактора и поковыряться на предмет всплывающего окна)
avatar
Отлично!
Для всплывающего окна просто можно буквально скопировать стиль с загрузки изображений. Там главное, чтобы позиционирование было абсолютным.
avatar
Нашлась картинка?
avatar
угу. непомню откуда вырезал картинку динамика. у меня mp3 загружаются, так что мне проще :)
avatar
очень полезная штука, но есть одно большое но. я сам не поставил timeice, вы (и админ) можете удалять с сайта ненужные файлы или нет?
avatar
Нет, все тоже самое как с картинками. То есть файлы складываются в папки, но используются они или нет никак не проверяется. То есть фактически возможна пачка файлов, которые вообще просто лежат.

Ort как-то упоминал о том, что возможно сделать мусорщик, который будет проверять подобные файлы и удалять их… Ну а пока оно работает без этого.
avatar

у меня тут вопрос возник. допустим я имею массив
$fileTypes = array(«exe», «rar», «mp3», «avi», «flv»);

подскажите как сделать проверку по этому массиву и в зависимости от типа файла подставлялся свой код. например вместо
if (!is_null($sFile)) {
                        $bStateError = false;
                        $alt = (isset($_REQUEST['title']) and mb_strlen(trim($_REQUEST['title'], 'UTF-8')))? $alt = $_REQUEST['title'] : false;
                        $sText = '<a href="'.$sFile.'">' . (($alt!=false)? $alt : 'Файл для скачивания') . '</a>';
для exe и rar файла поставлялось бы
if (!is_null($sFile)) {
                        $bStateError = false;
                        $alt = (isset($_REQUEST['title']) and mb_strlen(trim($_REQUEST['title'], 'UTF-8')))? $alt = $_REQUEST['title'] : false;
                        $sText = '<video>'.$sFile.'</video>';

для mp3, avi, и flv файлов?
avatar
Ох не советовал бы я так делать конечно, ибо вам так никакого сервера может не хватить… Но в целом — там есть проверка на поиск в массиве разрешенных типов. Вставьте вместо нее свою расширенную проверку и всех делов. :)
avatar
Сделал. Получилось. Автору — спасибо! Только вот многие моменты не описаны, пришлось прилагать моск ;)

зы: иконку бы еще где взять подходящую…
avatar


Вот вам ^^)
avatar
Многие — это какие именно? :)
avatar
Если скопировать и разместить предложенный код — работать не будет ;))) Так что повозиться пришлось. Да и схема реализации далека от совершенства — тоже пришлось повозиться.
avatar
Ну может просто изменилось что-то с тех пор уже. Так как на момент создания точно все работало. А для версии из SVN я вообще никак это не примерял.
avatar
Хз Хз, у мну шаблон к svn не имеет отношения вовсе.
avatar
И еще вопрос — каким образом сделать ограничение по размеру файла?
avatar
посредством php.ini не устраивает?
avatar
Если ничего не путаю, то таким образом можно отвергать файлы только после из загрузки.
avatar
или еще вариант вставить сразу после
<code>
if (is_uploaded_file($_FILES['usr_file']['tmp_name'])) {
               
                if(!($ext = strtolower(substr($_FILES['usr_file']['name'], (strrpos($_FILES['usr_file']['name'], ".") + 1))))) {
                        $sText = 'Не удалось определить тип файла...';
                } elseif(!in_array($ext, $fileTypes)) {
                        $sText = 'Для загрузки можно использовать только файлы следующих типов: ' . implode(', ', $fileTypes);
                }
</code>


данную строчку
<code>elseif($_FILES["usr_file"]["size"] > 1024*10*1024){
$sText ='Размер файла в мегабайтах не должен превышать 10;
                }
</code>


Но я так и не разобрался, как сделать переменную. Carw, если не трудно, то дополни :)
avatar
С этим делом надо как-то тоньше разобраться, чтобы это все совместно с сервером работало… Короче подумаю на выходных как сделать и отпишу :-)
avatar
Хм. Вот я нуб. Сделал вроде всё, что нужно. Допёр и до добавления кнопчки с иконкой. Но работаьб заливка не хочет. И на тип файла не проверяется, да и, если скорммить то что нужно, файл заливается, но в тест топика ничего не добавляется. Подскажитею
  • hint
  • 0
avatar
Сделай шаблон формы в отдельный файл — window_load_file.tpl, а в в шаблон actions/ActionTopic/add.tpl вставь не код формы, а строку {include file='window_load_file.tpl' sToLoad='topic_text'}

Смысл в том, что в предложенном выше решении собранное в переменной $sToLoad не передается в поле с текстом топика. А в моем передается ;)

Что же касается проверки на тип файла, то у меня она работает, но работает криво. Определяется не в момент загрузки, а уже после. И единственная реакция это появление списка разрешенных типов на окошке со статусом загрузки. Как решить этот вопрос я даже и не думал пока.
avatar
Стоп, стоп… что где и куда не передается? :-))
avatar
Я хз ;))) Но так работает, а как предложено выше — нет. Вот и вся разница как говориться.
avatar
Ну если честно, то у меня тоже этот диалог в отдельном файле подключен также… :-)
avatar

Но можно сделать так:

onclick="ajaxUploadFile(document.getElementById('form_upload_file'),'topic_text');"
avatar
Вот сам и ответил на свой вопрос ;)
avatar
Ну это не мой скорее, а тех, кто еще не сделал :))

Поправил в топике.
avatar
В последней версии LS нет main.js
Как поступить?
В какой директории создавать main.js?
avatar
Добавить в другой JS-файл :-)
avatar
Штука офигенная, но, похоже, заброшенная. А жаль, хотел приспособить ее для выкладывания видео.

Как сделал я (0.3.1):

1. Файл создан.
2. upload.js создан с этим содержим и он подгружается.
3. добавлено

{include file='window_load_file.tpl' sToLoad='topic_text'}


в add.tpl, создан сам window_load_file.tpl и в него засунут передраный код из window_load_img.tpl:

<div style="display: none;">
<div class="login-popup upload-image" id="window_load_file">
	<div class="login-popup-top"><a href="#" class="close-block" onclick="return false;"></a></div>
	<div class="content">
		<form method="POST" action="" enctype="multipart/form-data" id="form_upload_file" >
			<h3>Загрузка файла</h3>
			<p><label for="usr_file">Файл:</label><br /><input type="file" name="usr_file" value="" class="w100p" /></p>
			<p><label for="text">Описание:</label><br /><input type="text" name="title" value="" class="w100p" />
			<p style="margin-bottom: 20px;"><label for="title">{$aLang.uploadimg_title}:</label><br /><input type="text" class="w100p" name="title" value="" /></p>
			<input type="button" value="Загрузить" onclick="ajaxUploadFile(document.getElementById('form_upload_file'),'topic_text');">
			<input type="button" value="Отмена" onclick="closeWindow('window_load_file'); return false;">
		</form>
	</div>
	<div class="login-popup-bottom"></div>
</div>
</div>


потом в add.tpl дополнительно после кнопочки с картинками прописано:

<a href="#" onclick="ajaxUploadFile(document.getElementById('form_upload_file'),'topic_text');"><img src="{$DIR_STATIC_SKIN}/images/panel/img.gif" width="20" height="20" title="{$aLang.panel_image}"></a>


Кнопочка появляется, но не нажимается. Я уверен что пропустил или не заметил что-то очень важное, помогите плз.
avatar
Вы смотрите как сделана загрузка картинок. Там точно еще в некоторых местах надо править. (Например upload.js — он для 0,2 версии написан, в 0,3 весь яваскрипт был переписан — сообвественно для картинок тоже переписано — надо смотреть как там сделано теперь)
Сейчас как раз принимаюсь докручивать подобные мелочи — как прикручу — выложу.
avatar
Привет!!! Под 0.3 у тебя еще нет хака?
avatar
Действительно многое поменялось. Если раньше окно загрузки просто появлялось и скрывалось, то теперь принцип совсем другой. Также нужно переделывать обработчик на php.
avatar
Проблема в функции function ajaxUploadFile(value, sToLoad)

неплохо бы поправить кто умеет(
лично у меня не получилось
avatar
У кого нибудь на 0.3.1 заработало? просьба написать мануал для особенно тупых(

Увы я не смог разобраться(
avatar
Можешь дописать свой модуль под актуальную верси, пожалуйста?
avatar
Хак дописан товарищем Loki — стучитесь к нему.
avatar
Да, есть более продвинутый, хотя и платный аналог для загрузки файлов :-)
avatar
Это Вы про Модуль «Каталог LS» говорите? Хороший модуль… Но мне бы такой, чтобы из поста можно было бы прикреплять файлы к этому же посту (как картинки)…
avatar
Поиск только мне помогает?

www.livestreet.ru/blog/tips_and_tricks/1926.html
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.