Форумы xBB

Форумы xBB > BBCode и прочие языки упрощенной разметки

Upload картинок, как в FCKeditor'е

Автор: dima. Последнее редактирование: 2009-04-24 16:34:39

Получил письмо:
 
Добрый день, Дмитрий!
 
У меня к Вам есть вопрос по работе xBB с картинками!
В редакторе нужно знать где лежит картинка, сторонний человек не знает где лежит картинка.
В FCKeditore сделано очень удобно: получаем картинки, загружаем картинки и тд.
Можно ли организовать что-то подобное в данном редакторе?
 
Заранее спасибо!

Поскольку тема может быть интересна всем, то ответ решил дать публично.
 
Откройте файл bbcode/xbb.php. Найдите в нем код:
 
Text
<td><a href="#"
 onclick="xbb_insertLink('img', '<?php echo $xbb_lang['img_prompt']; ?>');return false;"
 class="toolbarButton"><img alt="[img]" src="./images/buttons/image.gif"
 id="img_img" /></a></td>

Этот - весь код, относящийся к вставке картинок. Больше ничего нет Well В этом коде рисуется кнопка для вставки картинки и на клик по ней назначается JS-функция вставки ссылок. Нам теперь нужно написать свою JS-функцию (или несколько), которые будут
  1. Выводить пользователю форму для выбора картинки.
     
  2. Средствами Ajax заливать выбранную картинку на сервер.
     
  3. Получать с сервера путь к залитой картинке.
     
  4. Формировать соответствующий BBCode и вставлять его в текст.

Кроме этого фронтенда нам следует написать бакенд (на PHP), который будет получать картинку от пользователя, сохранять её и возвращать на клиент адрес сохранённой картинки.
 
Библиотек для работы с Ajax'ом довольно много, и у каждого разработчика есть своя любимая. Дальше для определенности я буду использовать библиотеку JsHttpRequest Дмитрия Котерова. Выбор определился простотой и лаконичностью кода с использованием этой либы. Если вы используете другие библиотеки, то соответствующие куски кода должны переписать самостоятельно.

Backend

Это - минимальный рабочий код Backend'а:
 
PHP
<?php
// Подключаем JsHttpRequest. У вас путь к библиотеке будет, наверное, другим:
include_once './JsHttpRequest.php';
// Если надо, пофиксите кодировку:
$JsHttpRequest = new JsHttpRequest('utf-8');
 
// Сохраняем картинку. Пофиксите путь и все остальное:
$path = 'img/' . rand() . '.jpg';
move_uploaded_file($_FILES['img']['tmp_name'], $path);
$path = '/bbcode/test/' . $path;
 
// Отдаем фронтенду путь к картинке:
$_RESULT = array('path' => $path);

Этот код имеет следующие недостатки:
  1. Не проверяются права пользователя. Имеет он право заливать картинки или нет? Эта проверка необходима. Без этой проверки злоумышленник может положить вас сайт, заливая на него гигабайты картинок. Допишите эту проверку сами.
     
  2. Не проверяется корректность картинок. Допишите эту проверку сами. Проверяться должен тип и размер картинок. Имя файла должно формироваться соответственно типу.
     
  3. В случае неудачи скрипт не возвращает сообщения об ошибке. Это вы также должны пофиксить сами.
     
  4. Если пользователь в ходе редактирования текста откажется от использования уже залитой картинки, эта картинка останется лежать на серваке. Чистку такого мусора реализуйте сами.

Frontend

В файле bbcode/xbb.php меняем указанный в начале код на следующий:
 
HTML
<script type="text/javascript">
// Выводит форму для выбора картинки:
function img()
{
    xbb_buttonClick();
    var div = document.getElementById('hidden_div');
    if ('none' != div.style.display) {
        div.style.display = 'none';
        return false;
    }
    if (window.innerWidth) {
        var width = window.innerWidth;
    } else {
        var width = parseInt(xbb_editor.currentStyle.width);
    }
    div.style.top = (parseInt(xbb_height/2) - 100) + 'px';
    div.style.left = (parseInt(width/2) - 160) + 'px';
    div.innerHTML = '<div style="width:320px;height:180px;padding:10px">'
        + '<form onsubmit="imgSubmit();return false" name="imgOptions" '
        + '
method="post" enctype="multipart/form-data">
'
        + '<p>Введите адрес картинки:</p>'
        + '<input name="address" style="width:300px" />'
        + '<p>или залейте новую:</p>'
        + '<input type="file" name="img" style="width:300px" />'
        + '<br /><br />'
        + '<input type="submit" value="Готово" />';
        + '</form>'
        + '</div>';
    div.style.display = '';
    return false;
}
// Обрабатывает сабмит формы для выбора картинки:
function imgSubmit()
{
    var addr = document.imgOptions.address.value;
    if (addr) {
        imgInsert(addr);
        return;
    }
    xbb_startLoader();
    document.getElementById('loader').style.zIndex = "10";
    // (не забудьте подгрузить JsHttpRequest.js)
    var req = new JsHttpRequest();
    req.onreadystatechange = function() {
        if (req.readyState == 4) {
            imgInsert(req.responseJS.path);
        }
    }
    req.open(null, '/bbcode/test/backend.php', true);
    req.send({img: document.imgOptions.img});
}
// Формирует BBCode и вставляет его в текст.
function imgInsert(addr)
{
    document.getElementById('hidden_div').style.display = 'none';
    xbb_insertTags('[img]' + addr + '[/img]', '');
    xbb_stopLoader();
}
</script>
 
<td><a href="#" onclick="img();return false;"
 class="toolbarButton">
<img alt="[img]" src="./images/buttons/image.gif"
 id="img_img" />
</a></td>

В случае необходимости следует пофиксить путь к бакенду, внешний вид формы, добавить поля и т.п.
 
Пробуйте. Должно работать.

24 комментария

24.04.2009 17:46:28 #
Opera Гость Vlad
Что-то мне вот этот участок бэкенда не понравился
PHP
$path = 'img/' . rand() . '.jpg';
move_uploaded_file($_FILES['img']['tmp_name'], $path);
А вдруг такая картинка уже существовала?
Можно малость доработать
PHP
$path = '';
while (@is_file($path))
  $path = 'img/' . rand() . '.jpg';
move_uploaded_file($_FILES['img']['tmp_name'], $path);
24.04.2009 17:50:07 #
Iceweasel dima
Согласен. Я написал минимальный рабочий код, который обязан быть доработан.
24.04.2009 22:32:26 #
Opera Гость PilliGrim
Огромное спасибо за оперативный ответ!
И разъяснение ситуации. Думаю что приведенных Вами примеров для меня, как и для многих будет достаточно! Обязательно сегодня протестирую код!
Ещё раз спасибо!!!
24.04.2009 23:20:07 #
Iceweasel dima
Пожалуйста Well
16.07.2009 15:26:03 #
Mozilla Firefox Alien
эмм.. у меня нет файла JsHttpRequest.php
может поэтому файл не загружается?
17.07.2009 12:02:33 #
Iceweasel dima
JsHttpRequest - это отдельная библиотека, которую надо брать здесь: http://dklab.ru/lib/JsHttpRequest/
17.07.2009 12:41:30 #
Mozilla Firefox Alien
PHP
<?php
// Подключаем JsHttpRequest. У вас путь к библиотеке будет, наверное, другим:
include_once 'lib/JsHttpRequest/JsHttpRequest.php';
// Если надо, пофиксите кодировку:
$JsHttpRequest = new JsHttpRequest('utf-8');
 
// Сохраняем картинку. Пофиксите путь и все остальное:
while (@is_file($path))
$path = '/images/upload/' . rand() . '.jpg';
move_uploaded_file($_FILES['img']['tmp_name'], $path);
$path = '' . $path;
 
// Отдаем фронтенду путь к картинке:
$_RESULT = array('path' => $path);
?>
не работает Not so
при нажатии на кнопку готово, textarea сбрасывается и файл не загружается
17.07.2009 14:39:46 #
Iceweasel dima
Исправьте путь к картинкам. Сомневаюсь, что они именно так в файловой системе вашего сервера расположены.
17.07.2009 19:30:48 #
Mozilla Firefox Alien
нет, именно так. В корневой папке лежит папка images, а в ней находится папка upload. путь указан верно.
17.07.2009 23:36:23 #
Iceweasel dima
Не может быть так. Есть разница между корневой папкой вашего сайта и корневой папкой вашего сервера. Если ваши картинка будет доступна по адресу
 
http://мой.сайт/images/upload/123456.jpg
 
то в путь к картинке в файловой системе сервера может выглядеть так:
 
/home/мой.сайт/public_html/images/upload/123456.jpg
 
или иначе. Видите разницу?
Поэтому, если Вы средствами PHP будете обращаться по адресу
 
/images/upload/123456.jpg без предшествующих /home/мой.сайт/public_html,
 
То получите ошибку. Собственно уже получили
Используйте относительные пути по файловой системе.

Ответить:

Представиться как     Антибот:
   

Просьба не постить мусор. Пользуйтесь кнопкой предварительного просмотра на панели инструментов редактора.

Введите логин: и пароль: (

© 2007-2017, Дмитрий Скоробогатов.
Разрешается воспроизводить, распространять и/или изменять материалы сайта
в соответствии с условиями GNU Free Documentation License,
версии 1.2 или любой более поздней версии, опубликованной FSF,
если только иное не указано в самих материалах.