PHP

Zend Framework: WYSIWYG + FileBrowser

Здравствуй, неизвестный читатель. На просторах интернета я не встретил толковой реализации, кроме одной, ссылку на которую я вставлю в конце поста.
После проделывания всех шагов, описанных в этом посте, у вас будет иметься возможность вставлять в форму визуальный редактор с файловым менеджером парой строк:
        <?php
                $wysiwyg = new Vredniy_Form_Element_WysiwygElrte(&apos;content&apos;, array(
                    &apos;label&apos; => &apos;Контент&apos;
                ));

               $this->addElement($wysiwyg);
               ?>

Не правда ли удобно? Итак, начнем все подробно разбирать.
Шаг номер 1. Качаем elrte и elFinder с официального сайта. Здесь ни у кого не должно возникнуть сложностей. Дальше, чтобы не путаться в путях предлагаю эти библиотеки разместить как у меня. /public/elrte и /public/elfinder соответственно.

Шаг номер 2. Создаем кастомизированный элемент формы Vredniy_Form_Element_WysiwygElrte (над названием, скорей всего нужно будет подумать)
<?php
class Vredniy_Form_Element_WysiwygElrte extends Zend_Form_Element_Xhtml
{
    public $helper = &apos;formWysiwygElrte&apos;;
}
?>

Этот элемент формы будет вести себя как стандартный зендовский. Теперь напишем свой вью хелпер (шаг 3), который и будет заниматься всей грязной работой: подключать все необходимые скрипты, стили и генерировать контент исходного элемента формы.
   <?php
class Vredniy_View_Helper_FormWysiwygElrte extends Zend_View_Helper_FormElement 
{

    public function formWysiwygElrte($name = null, $value = null, $attribs = null)
    {
        if (!$this->view->jQuery()->isEnabled())
                $this->view->jQuery()->enable();

        if (!$this->view->jQuery()->uiIsEnabled())
                $this->view->jQuery()->uiEnable();


        $elrte_base_uri = "/js/elrte/";

        $this->view->headLink()->appendStylesheet("{$elrte_base_uri}css/elrte.full.css");
        $this->view->headScript()->appendFile("{$elrte_base_uri}js/elrte.full.js");
        $this->view->headScript()->appendFile("{$elrte_base_uri}js/i18n/elrte.ru.js");

        
        $elfinder_base_uri = "/js/elfinder/";
        $this->view->headLink()->appendStylesheet("{$elfinder_base_uri}css/elfinder.css");
        $this->view->headScript()->appendFile("{$elfinder_base_uri}js/elfinder.full.js");
        $this->view->headScript()->captureStart() ?>
            var opts = {
                lang : &apos;ru&apos;,
                styleWithCss : false,
                absoluteURLs: false, // чтобы отображался не полный путь, а относительный от корня
                width   : 800,
                height  : 200,
                toolbar : &apos;maxi&apos;, // все возможные панели инструментов, удалить легче :)
                fmAllow  : true,
                fmOpen   : function(callback) {
                    $(&apos;<div id="myelfinder" />&apos;).elfinder({
                        url : &apos;<?php echo $elfinder_base_uri; ?>connectors/php/connector.php&apos;,
                        lang : &apos;ru&apos;,
                        dialog : {
                            width : 900, // ширина файлового менеджера
                            modal : true,
                            title : &apos;Выбираем файлик&apos;
                        }, // открываем в диалоговом окне
                        closeOnEditorCallback : true, // закрываем после выбора файла
                        editorCallback : callback
                    })
                }
            };

            $().ready(function() {
              // создаем редактор
                $(&apos;#<?php echo $name; ?>&apos;).elrte(opts);
            });
        <?php $this->view->headScript()->captureEnd();

        $info = $this->_getInfo($name, $value, $attribs);
        extract($info); // name, value, attribs, options, listsep, disable

        // is it disabled?
        $disabled = &apos;&apos;;
        if ($disable) {
            // disabled.
            $disabled = &apos; disabled="disabled"&apos;;
        }

        // build the element
        $xhtml = &apos;<textarea name="&apos; . $this->view->escape($name) . &apos;"&apos;
                . &apos; id="&apos; . $this->view->escape($id) . &apos;"&apos;
                . $disabled
                . $this->_htmlAttribs($attribs) . &apos;>&apos;
                . $this->view->escape($value) . &apos;</textarea>&apos;;

        return $xhtml;
        
    }

}
   
?>

В исходном коде я старался максимально комментировать не особо очевидные моменты, кроме подключения jQuery и jQueryUI (как их подключить расскажу в конце, чтобы не отвлекать вас от основной идеи).

Шаг 4. Изменяем опции коннектора, который отвечает за файловый менеджер public/js/elfinder/php/connector.php
<?php
// из основного файла ZF index.php я вынес в отдельный
// константы, чтобы было удобно их подключать извне
require_once realpath(dirname(__FILE__) . &apos;/../../../../constants.php&apos;);
error_reporting(0); // Set E_ALL for debuging

if (function_exists(&apos;date_default_timezone_set&apos;)) {
   date_default_timezone_set(&apos;Europe/Moscow&apos;);
}

include_once dirname(__FILE__).DIRECTORY_SEPARATOR.&apos;elFinder.class.php&apos;;

/**
 * Simple example how to use logger with elFinder
 **/
class elFinderLogger implements elFinderILogger {
   
   public function log($cmd, $ok, $context, $err=&apos;&apos;, $errorData = array()) {
      if (false != ($fp = fopen(&apos;./log.txt&apos;, &apos;a&apos;))) {
         if ($ok) {
            $str = "cmd: $cmd; OK; context: ".str_replace("\n", &apos;&apos;, var_export($context, true))."; \n";
         } else {
            $str = "cmd: $cmd; FAILED; context: ".str_replace("\n", &apos;&apos;, var_export($context, true))."; error: $err; errorData: ".str_replace("\n", &apos;&apos;, var_export($errorData, true))."\n";
         }
         fwrite($fp, $str);
         fclose($fp);
      }
   }
   
}

$opts = array(
    &apos;root&apos;            => APPLICATION_PUBLIC . &apos;/upload/files&apos;, // path to root directory
    &apos;URL&apos;             => &apos;/upload/files/&apos;, // root directory URL
    &apos;rootAlias&apos;       => &apos;Галерея&apos;, // display this instead of root directory name
);

$fm = new elFinder($opts); 
$fm->run();
?>

Тут самое интересное это массив $opts, в котором мы задаем корневую папку нашего файлового хранилища и меняем название «Home» на более привычное русскому глазу «Галерея».

Шаг 5 (костыль). У меня не получилось «из коробки» заставить принимать правильный размер диалоговое окно, поэтому я заменил 6303 строчку в файле /js/elrte/js/elrte.full.js на свое
         width    : 670,
                                // @todo: чтобы помещалась волшебная кнопочка

Шаг 6. Подключаем скрипты jQuery, jQuery и необходимые для них стили. Корневой файл Bootstrap.php
<?php
    protected function _initViewHelpers()
    {
        $this->bootstrap(&apos;layout&apos;);
        $layout = $this->getResource(&apos;layout&apos;);
        $view = $layout->getView();
        $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper(&apos;viewRenderer&apos;);
        $viewRenderer->view->addHelperPath("Vredniy/View/Helper", &apos;Vredniy_View_Helper&apos;);

        // init 960gs-fluid
        $view->headLink()->appendStylesheet(&apos;/css/960gs-fluid/reset.css&apos;)
                ->headLink()->appendStylesheet(&apos;/css/960gs-fluid/text.css&apos;)
                ->headLink()->appendStylesheet(&apos;/css/960gs-fluid/grid.css&apos;)
                ->headLink()->appendStylesheet(&apos;/css/960gs-fluid/layout.css&apos;)
                ->headLink()->appendStylesheet(&apos;/css/960gs-fluid/ie/ie6.css&apos;, &apos;all&apos;, &apos;IE6&apos;)
                ->headLink()->appendStylesheet(&apos;/css/960gs-fluid/ie/ie.css&apos;, &apos;all&apos;, &apos;IE&apos;)
        ;


        // init jQuery & UI
        ZendX_JQuery::enableView($view);
        $view->jQuery()
                ->setLocalPath(&apos;/js/jquery/jquery-1.4.4.min.js&apos;)
                ->setUiLocalPath(&apos;/js/jqueryui/jquery-ui-1.8.10.custom.min.js&apos;)
                ->addStylesheet(&apos;/css/jqueryui/themes/start/jquery-ui-1.8.10.custom.css&apos;)
        ;

        // set doctype
        $view->doctype(&apos;HTML5&apos;);

        // set title separator
        $view->headTitle()->setSeparator(&apos; :: &apos;);
    }
?>

jQuery располагаем в папку /js/jquery/, jQueryUI — в /js/jquery/ui и темы в /css/jqueryui/themes/

И последнее, разобьем наш файл /public/index.php на два: сам файл
<?php
require_once &apos;constants.php&apos;;
// Ensure library/ is on include_path
set_include_path(implode(PATH_SEPARATOR, array(
    realpath(APPLICATION_PATH . &apos;/../library&apos;),
    get_include_path(),
)));

/** Zend_Application */
require_once &apos;Zend/Application.php&apos;;

// Create application, bootstrap, and run
$application = new Zend_Application(
    APPLICATION_ENV,
    APPLICATION_PATH . &apos;/configs/application.ini&apos;
);
$application->bootstrap()
            ->run();
  
  
?>

и constants.php
<?php

// Define path to application directory
defined(&apos;APPLICATION_PATH&apos;)
        || define(&apos;APPLICATION_PATH&apos;, realpath(dirname(__FILE__) . &apos;/../application&apos;));

// Define application environment
defined(&apos;APPLICATION_ENV&apos;)
        || define(&apos;APPLICATION_ENV&apos;, (getenv(&apos;APPLICATION_ENV&apos;) ? getenv(&apos;APPLICATION_ENV&apos;) : &apos;production&apos;));

// public folder
defined(&apos;APPLICATION_PUBLIC&apos;)
        || define(&apos;APPLICATION_PUBLIC&apos;, realpath(APPLICATION_PATH . &apos;/../public&apos;));


?>

Дальше используем. Создадим форму с 2мя элементами: нашим wysiwyg’ом и простую кнопку submit. Сказано-сделано.
<?php

class Static_Form_Page extends Zend_Form
{

    public function init()
    {
        $wysiwyg = new Vredniy_Form_Element_WysiwygElrte(&apos;content&apos;, array(
                    &apos;label&apos; => &apos;Контент&apos;
                ));
        // @todo add filters and validators

        $this->addElement($wysiwyg);
        $this->addElement(&apos;submit&apos;, &apos;submit&apos;, array(
            &apos;label&apos; => &apos;Change me&apos;
                // @todo add filters and validators
        ));
    }

}

?>

И в каком-нибудь контроллере напишем следующее:
<?php

class Static_AdminController extends Zend_Controller_Action
{

    public function indexAction()
    {
        $form = new Static_Form_Page();
        $form->getElement(&apos;submit&apos;)->setLabel(&apos;Создать&apos;);
        $this->view->form = $form;
        if ($this->getRequest()->isPost()) {
            if ($form->isValid($this->getRequest()->getPost())) {
                var_dump($form->getValues());
            }
        }
    }

}
?>

В соответствующем скрипте вида напишем пару строк для вывода формы
Форма с Wysisyg и FileBrowser&apos;ом
<?php echo $this->form; ?>

Спасибо за потраченное на чтение сего поста время, надеюсь, информация вам оказалась полезной.
Добавлено: 01 Января 2015 18:11:31 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...