Подключаем FCKeditor к CodeIgniter

22 ноября, 2008
fckeditor codeigniter

FCKeditor, на мой взгляд, один из лучших online редакторов. И в теории его можно подключить практически к любому сайту, независимо от того какой движок/фреймворк/CMS используется.

Но, естественно, всегда существует несколько нюансов, которые немного усложняют жизнь :-)

В этой статье речь пойдет о том как подключить этот редактор к сайту использующему PHP фреймворк CodeIgniter. Вообще-то я нашел довольно много статей и рекомендаций на эту тему, но в большинстве из них предлагается скопировать файлы редактора в папки библиотек или плагинов, а, на мой взгляд, это не правильно.

Дело вот в чем. Плагины и библиотеки (пользовательские) обычно находятся в папке application, которая не обязательно должна находиться внутри DOCUMENT_ROOT. Точнее, с точки зрения безопасности, эту папку лучше убрать за пределы DOCUMENT_ROOT чтобы исключить любую возможность прямого доступа к скриптам сайта (т.е. скрипты будут доступны только через index.php).

Но FCKeditor содержит файлы картинок, стилей и т.п., к которым нужно обеспечить прямой доступ. Т.е. его нужно разместить внутри DOCUMENT_ROOT.

Как оказалось, обойти эту проблему совсем не сложно.

Прежде всего, рассмотрим структуру папок сайта.

index.php
system/
fckeditor/
images/
css/
libs/

Как видите, в корне сайта (DOCUMENT_ROOT) находятся главный контроллер (index.php), папки system, fckeditor (с редактором) и другие папки с картинками, CSS стилями, библиотеками и т.п.

Папка application по-умолчанию находится внутри system, но ее можно спокойно перенести.

Подключаем редактор

Прежде всего, создадим файл настроек (application/config/fckeditor.php)

  1. <?php
  2. //путь к FCKeditor относительно корня сайта (папки, в которой находится index.php)
  3. $config['fckeditor_path'] = 'fckeditor/';
  4. //URL FCKeditor относительно корня сайта (параметра $config['base_url'])
  5. $config['fckeditor_url'] = 'fckeditor/';
  6. //имя редактора
  7. $config['fckeditor_name'] = 'MyFCKeditor';
  8. //высота редактора
  9. $config['fckeditor_height'] = 300;
  10. ?>

Объяснять тут в общем-то нечего. Главное правильно указать параметры fckeditor_path и fckeditor_url.

Теперь создадим файл библиотеки, который будет подключать редактор (/application/libraries/fcke.php).

  1. <?php
  2. if ( ! defined('BASEPATH')) exit('No direct script access allowed');
  3. /**
  4.  * Эта библиотека подключает редактор FCKeditor
  5.  *
  6.  * @version 0.1
  7.  * @link http://www.simplecoding.org
  8.  * @author Стаценко Владимир <vova_33@gala.net>
  9.  */
  10. class FCKe {
  11.    
  12.     private $editor = null;
  13.    
  14.     function FCKe() {
  15.         $CI = &amp;get_instance();
  16.         //читаем данные из конфига
  17.         $CI->config->load('fckeditor');
  18.         $fcke_url = $CI->config->item('base_url').$CI->config->item('fckeditor_url');
  19.         $fcke_path = substr(FCPATH, 0, strrpos(FCPATH, DIRECTORY_SEPARATOR) + 1)
  20.             .$CI->config->item('fckeditor_path');
  21.         include_once($fcke_path.'fckeditor.php');
  22.         $this->editor = new FCKeditor($CI->config->item('fckeditor_name'));
  23.         $this->editor->BasePath = $fcke_url;
  24.         $this->editor->Height = $CI->config->item('fckeditor_height');
  25.     }
  26.  
  27.     function __call($method, $arguments) {
  28.         return call_user_func_array(array($this->editor, $method), $arguments);
  29.     }
  30. }
  31. /* End of file fckeditor.php */
  32. /* Location: ./system/application/libraries/fckeditor/fckeditor.php */

Разберем этот код подробнее.

В конструкторе мы читаем параметры из конфига, загружаем файл fckeditor.php и создаем объект редактора (FCKeditor).

Параметр fckeditor_path используется при загрузке файла fckeditor.php (строка 21). А с помощью fckeditor_url задаем URL папки редактора (строка 23).

Доступ к методам редактора обеспечивает метод __call.

Проще говоря, мы написали оболочку, которая загружает редактор и обеспечивает доступ ко всем его методам.

Теперь использовать редактор не сложнее чем любую другую библиотеку CodeIgniter.

В контроллере загружаем библиотеку:

  1. $this->load->library('fcke');

И сразу же можем создать редактор.

  1. $this->fcke->Create();

Как видите, метод Create() редактора вызывается через объект fcke, т.е. нашу библиотеку.

Примечание. Редактор должен находится внутри формы. Атрибут action указывает какому скрипту будет отправлен текст, введенный в редактор.

Небольшое дополнение. Метод Create() сразу же отправляет код редактора браузеру, т.е. его нужно вызывать из представления. В общем-то, ничего страшного, но это нарушение MVC модели. Если хотите этого избежать используйте метод CreateHtml() в контроллере. Он возвращает HTML код редактора, который затем можно передать представлению. Например:

в контроллере:

  1. $this->load->library('fcke');
  2. $pageData['editor'] = $this->fcke->CreateHtml();
  3. $this->load->view('my_view', $pageData);

в представлении:

  1. <?php
  2. echo $editor;
  3. ?>

В общем, подключить редактор не сложно.

Если у вас есть замечания или вопросы, буду рад на них ответить. Пишите, комментарии открыты!

Понравилась статья? Подписывайтесь на продолжение rss link !

Или на мой твиттер twitter link

]]>

Добавьте эту страницу в google.com bobrdobr.ru del.icio.us technorati.com linkstore.ru news2.ru rumarkz.ru memori.ru moemesto.ru

]]>

Опубликовано в CodeIgniter, PHP, Web разработка View Comments

]]>
  • Evgeniyzaritskiy
    Не парьтесь ребята читайте с офф сайта как правильно конектить
    http://codeigniter.com/wiki/FCKeditor/
  • oFCKeditor->Value

    как это работает в вашем примере?
  • Насколько я понял, это вопрос к комментарию Валерия.
    Свойство Value позволяет записать текст в редактор, только использовать его нужно немного по другому.
    Например, так:
    $out.='oFCKeditor.Value = "Some text";';
  • а как в таком варианте передать:
    $oFCKeditor->Value
  • Владимир. Не совсем уловил разницу в $config['fckeditor_path'] и $config['fckeditor_path']. fckeditor.php обычно всегда лежит в папке с fckeditor. Ну да ладно.
    Следовал инструкции. Однако во фрейме, где должен появляться редактор, у меня "404 - страница не найдена".
    в конфигах
    $config['fckeditor_path'] = 'fckeditor/';
    $config['fckeditor_path'] = 'fckeditor/';

    редактор лежит по адресу www.site.ru/fckeditor
    В хтаксесс изменения внесены.

    PS С сайта оч не удобно копировать исходник ((
  • Вы, наверное, имели ввиду config['fckeditor_path'] и config['fckeditor_url']. Согласен, в большинстве случаев они совпадают, поэтому можно использовать и одну настройку.

    Я отправил вам почтой архив с рабочим примером, чтобы можно было сравнить настройки.
  • Во-первых надо так $config['fckeditor_path'] = '/fckeditor/';
    А во-вторых есть лучший способ сдесь http://php-velosiped.org.ua/2008/12/01/139.html
  • Не уверен :-) Хелпер, конечно, получился короткий и выглядит красиво, только что делать если потребуется доступ к методам $oFCKeditor?

    мы тогда модифицируем хелпер
  • немного изменил хелпер
    http://php-velosiped.org.ua/2008/12/01/139.html
    теперь мне кажеться что это единственный правильный способ
  • Я смотрю по комментариям, вроде этот пост уже обсуждали...
    Я так понял убрана генерация JS? Это правильное решение ;)

    единственный правильный способ


    Не уверен :-) Хелпер, конечно, получился короткий и выглядит красиво, только что делать если потребуется доступ к методам $oFCKeditor?

    P.S. Сразу признаю, что в 99% случаев эти методы не используются :-)
  • Be3
    Здравствуйте.
    Каким образом можно подключить 2ой редактор на странице ?
    Судя по коду, такая возможность не предусмотрена.
  • Be3
    Спасибо, разобрался, через __set +)
  • Aderba
    Здравствуйте подскажите пожалуйста как мне достать введенное значение из FCKEditor только в javascript?
    Сейчас как он работает так что вводим какие-то данные потом по нажатию submit, эти данные как-то заносятся в скрытое поля а потом уже передаются, так вот мне нужно достать данные из FCKEditor до того как нажата submit...подскажите пожалуйста как быть. Спасибо!
  • Поле редактора представляет собой iframe, который находится внутри другого iframe :-)
    Т.е. вам нужно посмотреть разметку вашей страницы и вытянуть содержимое нужного iframe.
    Но разве не проще сделать плагин к редактору (свою кнопку)?
  • Я тут немного поворчать хочу.

    А как у FCKeditor с корректностью кода? Просто попользовавшись визуальным редактором в WordPress, я несколько негативно отношусь ко всем визуальным редактором и пользуюсь невизуальным :)

    На мой взгляд, это достаточно удобно и всегда уверен, что получишь именно то, что хочешь.
  • Я отвечу просто - режим html в редакторе есть. :)
  • удачи
  • Просто мне не очень нравиться генерировать JS код на PHP, особенно когда без этого можно обойтись :-)

    Согласен, но когда идет речь о выбросе кода как единой логической единицы, то можно. А преимущество есть - редактор это логика представления, и писать что-то в бизнес логике для вывода редактора неправильно [1],[2].
    ----------------------
    [1]Мартин Фаулер."Архитектура корпоративного программного обеспечения".
    [2]Мартин Фаулер.Рефаткоринг.
  • >> редактор это логика представления

    Согласен, вы правы. Но представьте ситуацию. Есть контроллер с несколькими методами, каждый из которых создает представление с редактором. В соответствии с паттерном, вы должны вызвать хелпер в каждом из этих представлений, а это - дублирование кода. Можно вызвать этот же хелпер в конструкторе и присвоить код какой-нибудь переменной, которую потом выводить в представлении.
  • Не пойму про что вы говорите. Хелпер я запускаю в шаблоне и подключаю его там же.В контроллер я вообще не лезу.Почитайте внимательно ссылку на мой блог.

    В соответствии с паттерном, вы должны вызвать хелпер

    О каком паттерне идет речь я вообще непойму.

    И никакого дублирования кода нет, накрайняк подключаю в конструкторе хелпер (а вообще правильно в шаблоне каждый раз), но в переменную загонять нет вообще смысла. Во-первых зачем ее все время передавать в шаблоны (на каждой странице). Во-вторых а если я захочу где-то вывести редактор с другими насторойками, что тогда? В -третьих - какая разница что писать в шаблоне так echo var или так echo fcke()
  • О каком паттерне идет речь


    MVC

    накрайняк подключаю в конструкторе хелпер (а вообще правильно в шаблоне каждый раз)


    Как раз об этом и речь. Правильно в представлении, а удобнее - в конструкторе контроллера.

    Согласен, разницы между echo var или так echo fcke() нет. Но если пример будет немного сложнее и нужно будет настраивать редактор (вызвать его методы), и эти настройки будут одинаковы для разных страниц шаблона, то удобнее выполнить этот код один раз в конструкторе.

    а если я захочу где-то вывести редактор с другими насторойками


    Создавать как обычно, т.е. использовать конструктор имеет смысл если редактор не меняется.

    Честно говоря, мне понравился ваш вариант, и, может быть, я буду им пользоваться... как минимум буду иметь ввиду :-)
    Просто я хочу сказать, что бывают ситуации, когда строгое соблюдение методологий и паттернов (того же MVC) усложняет код. Этот пример не очень удачный, т.к. слишком простой и выигрыш заключается всего в паре строк кода (если он вообще есть).
  • Тоже вариант. И, согласен, он короче моего.
    В вашем примере используется JavaScript подключение, я использовал вариант с PHP.
    В общем-то ни тот, ни другой вариант особых преимуществ не дает (оба стандартные и библиотеки для них входят в дистрибутив редактора).
    Просто мне не очень нравиться генерировать JS код на PHP, особенно когда без этого можно обойтись :-)
  • Вот ссылка на статью на мой блог
  • защита от XSS на вашем сайте порезала мне комент.
  • Что именно порезало?
  • Делаеться это так:
    Заливаеться редактор в корень проекта и в system/helpers/form_helper.php пишеться ф-я fcke()
    Это на быструю руку, вообще пользовательские хелперы туда лучше не писать.

    function fcke($name='FCKeditor1',$basePath='/fckeditor/',$width='600px',$height='400px')
    {
    $out=''."\n";
    $out.='';
    $out.='var oFCKeditor = new FCKeditor(\''.$name.'\');'."\n";
    $out.='oFCKeditor.BasePath = "'.$basePath.'";'."\n";
    $out.='oFCKeditor.Width = "'.$width.'";';
    $out.='oFCKeditor.Height = "'.$height.'";';
    $out.='oFCKeditor.Create();
    ';
    return $out;
    }

    Вот и все дело с концом все очень просто. Пишеться за 30 сек.И удобно подключать.
  • Эх, Валерий, вы меня опередили ) Точно такое же решение хотел предложить. Единственное не нужно редактировать файл system/helpers/form_helper.php, гораздо лучше создать хелпер в директории application с именем MY_form_helper.php (это по умолчанию). CI, в этом случае, при загрузке хелпера form, сначала загрузит файл MY_form_helper.php, а затем form_helper.php
  • В данном случае для класса FCKe нужно еще добавить следующий метод:

    function __set($name, $value)
    {
    $this->editor->$name = $value;
    }


    иначе как передавать значение в текстовое поле?
  • Полностью согласен. Присвоить значение свойству класса через __call не получится.
    Правда, проблему можно решить по-другому. Например, если нужно вставлять предварительно подготовленные фрагменты текста в редактор, то лучше сделать это с помощью JavaScript, чем перегружать страницу и вставлять этот текст на стороне сервера.
  • Владимир, объясните, пожалуйста, чем лучше. Вот, к примеру:
    $this->fcke->Value = $data['text'];
    $data['editor'] = $this->fcke->CreateHtml();


    Получили данные из модели, передали значение в редактор, получили код редактора и передаем в представление. О какой перезагрузки страницы идет речь?
  • >> О какой перезагрузки страницы идет речь?

    Прошу прощения, не удачно написал предыдущий комментарий.

    Я имел в виду, что обычно добавлять готовый текст в редактор нужно в ответ на действие пользователя. Например, если он хочет загрузить какой-то шаблон.

    Т.е. посетитель нажимает на кнопку в интерфейсе - в редакторе появляется текст.
    Эту функцию лучше реализовать на JS (при необходимости подгрузить данные через AJAX).
    А при создании страницы с редактором просто оставить пустое поле.
  • До инициализации класса библиотеки CI пытается сам загрузить файл конфигурации, имя которого соответствует имени класса. Соответственно, конфигурационный файл можно было назвать fcke и отказаться от его загрузки в конструкторе. Или есть какие-либо ограничения?
  • Честно говоря, раньше не слышал об этой возможности. И к тому же у меня не работает. В общем, мне проще явно загрузить файл.
  • Да, действительно, не работает. Я просто когда копался "во внутренностях" CI в классе Loader обнаружил следующее:
    function _ci_init_class($class, $prefix = '', $config = FALSE)
    {
    $class = strtolower($class);

    // Is there an associated config file for this class?
    if ($config === NULL)
    {
    if (file_exists(APPPATH.'config/'.$class.EXT))
    {
    include_once(APPPATH.'config/'.$class.EXT);
    }
    }
    ...
    }


    В памяти отложилось, что происходит загрузка конфига. Вот и подумал, что загруженные данные попадают в "глобальный" массив, до данных которого можно "достучаться" используя $CI->config->item()

    Интересно, тогда для чего разработчики предусмотрели такую возможность. Разве только для загрузки констант.
  • Когда-то у меня тоже стояла такая задача, но ни одно из решений в интеренте мне не подошло.
    В итоге придумал свой способ.
    Что мне ненравиться в СI, так это мешанина представления и контроллера. К примеру хелперы по идее недолжны подключаться в контроллере, но у игнайтера - это нормально. Собачки в коде - это плохо - у игнайтера хорошо. Когда-то пол часа потратил на отладку приложения на игнайтере, пока не полез в код и не повытирал собачки.
    Короче с недавних пор ненравиться мне игнайтер. Вообще я пишу всегда на symfony, но она негодится для маленьких проектов. Поэтому с недавних пор отдаю предпочтение не CI а написанному на его базе Kohana. Там намного более грамотный код.
    Редактор - это проблема представления, поэтому выход вижу только один- написать хелпер, который возвращает javaScript. При необходимости можно сделать хелпер кастамский, т.е передавать в качестве аргументов высоту и т.д. И ненадо ничего усложнять, как это сделано тут http://erum.ru/article/9.
    там чувак вывернул кишки из чего только мог.
    А располагаться эдитор должен только в одном месте - в корне сайта (как у Володи).Любое другое решение считаю - идиотизмом.
    P.S:Почему только среди php-шников столько неграмотности????!!!!
  • >там чувак вывернул кишки из чего только мог.
    1. хм. Учебный пример. К тому же два варианта - в одном вообще ни строчки php кода.
    2. я вообще считаю что вставка js непосредственно в HTML может быть оправдана только в исключительных случаях. Например в учебных примерах. В остальных такие вещи как визивиг или валидация должны подцепляться AJAXом. Но это отдельная тема.

    >А располагаться эдитор должен только в одном месте - в не сайта (как у Володи).
    >Любое другое решение считаю - идиотизмом
    Идиотизм - абсолютизировать любое техническое решение.
  • Идиотизм - абсолютизировать любое техническое решение


    Это правильно. Идеальных решений не существует и всегда лучше попробовать несколько вариантов и выбрать наиболее подходящий в данной ситуации.

    должны подцепляться AJAXом. Но это отдельная тема.


    Хотелось бы почитать статью на эту тему ;)
    По-моему использование AJAX может создать дополнительные задержки и не всегда они оправданны... без примера сложно что-то сказать.
  • Спасибо! Интересные статьи получились.
  • C большим опозданием, но смог оформить в виде текста:
    http://erum.ru/article/38 - подключение jwysiwyg
    http://erum.ru/article/39 - превращение jwysiwyg в FCK
  • Но ведь WYSIWYG будет подключаться только один раз, для формы редактирования поста. Для удаления спама он не нужен.

    Но кажется я понял о чем речь :) В админке WP форма быстрого редактирования комментариев подключается AJAX'ом.
  • > Но все равно мне не понятно почему подключение WYSIWYG
    > редактора должно выполняться ajax'ом?
    На примере того же блога - на одну операцию по редактированию текстов приходится десяток операций по управлению откликами (удаление спама, добавление редакторских откликов, управление тегами и т.п.). Спрашивается - нафига в этом случае постоянно грузить визивиг, а к нему еще десяток прибабахов?
  • Насчет админки и трудозатрат полностью согласен. С той же админкой WP 2.7 работать гораздо быстрее в основном за счет ajax.
    Но все равно мне не понятно почему подключение WYSIWYG редактора должно выполняться ajax'ом? Если редактор используется постоянно, то лучше сразу подключить его к странице.
  • >По-моему использование AJAX ....без примера сложно что-то сказать.
    Все в том же контексте. Имхо большая часть функций админки должна выносится непосредственно на фронтофис (за исключением каких-то отдельных функций). В этом случае либо iframe либо ajax.
    А экономия очень простая. Она даже не на трафике, а на трудозатратах по администрированию сайта. Юзабельность повышается на порядок.
  • >> хелперы

    Вопрос очень спорный:
    1) Form helper - создает html код (представление)
    2) File helper - работа с файлами (модель)
    3) Хелперы можно загружать через autoload в этом случае они скорее напоминают стандартные функции PHP и отнести их к контроллеру, модели и представлению сложно (во всяком случае для меня).

    >> Kohana и собачки

    Ничего против не имею, но сам с необходимостью вытирать собачки не сталкивался

    >> выход вижу только один- написать хелпер

    Честно говоря, работать с библиотекой мне кажется удобнее. Хотя, конечно, нужно написать хелпер и сравнить.

    >> чувак вывернул кишки

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

    >> располагаться эдитор должен только в одном месте

    Опять же, спорное заявление. Например, если редактор используется только для админ панели, то логично разместить его в папке, доступ к которой ограничен (а это не обязательно в корне сайта).

    >> P.S.

    Это вопрос риторический :-)
    Неграмотных разработчиков (также как и грамотных и талантливых) везде хватает. Врядли существует точная статистика.
    Хотя языки вроде С++ и Java страхуют от некоторых ошибок (например, за счет строгой типизации).
  • KomarBang
    По поводу подключения хелперов в контроллере...

    Как мне кажется это логично, что хелперы подключаются через контроллер. На то он и "контроллер"!

    А вооообще CI просто дает возможность подключения и там и там, а где подключать - это уже ваше решение. Хорошо, что есть выбор :)
  • Это еще одна мешанина в CI. Хелпер должен всегда генерить html или javaScript. Его дело это представление. То что в игнайтере хелперы работают с файлами - идиотизм. Это прерогатива библиотек.
    Посмотрите хоть на один грамотный фреймверк (Symfony and Zend).

    Честно говоря, работать с библиотекой мне кажется удобнее. Хотя, конечно, нужно написать хелпер и сравнить.

    Библиотека - это бизнес логика


    Эта фраза была бы уместнее в комментариях к той статье. Во всяком случае автор мог бы ответить.

    Мне не интересно его переубеждать.





    Опять же, спорное заявление. Например, если редактор используется только для админ панели, то логично разместить его в папке, доступ к которой ограничен (а это не обязательно в корне сайта).


    А зачем к нему ограничивать доступ.
  • Это еще одна мешанина в CI


    Может быть, но что будет если разработчики эту мешанину уберут? Станет CI эффективнее/быстрее/стабильнее? Вряд ли. Ведь только названия изменятся. Код будет тем же самым. Зато наверняка посыпятся жалобы от разработчиков.

    Вобщем, хелпер и библиотека - это только названия, условности. Главное - код, который за ними стоит.

    Я, конечно, понимаю, что было бы очень не плохо если бы все придерживались единой терминологии, но вносить изменения в движок только ради названий - это ИМХО перебор.

    А зачем к нему ограничивать доступ


    Просто дополнительная мера безопасности. Закрыть посетителям доступ ко всем скриптам, которые они использовать не должны (независимо от того есть уязвимости в скриптах или нет).
  • в каким образом без CreateHtml() можно обойтись?
  • Использовать метод Create(). Он сразу отправляет редактор браузеру.
blog comments powered by Disqus ]]>