Подытожим сегодня подключение fck и кое-что еще.
Итак. Задача - подключить fckeditor. Первый шаг, традиционно, - погуглить :) Полушутка. А подключать будем с помощью jquery, для чего скачаем актуальные:
- fckeditor;
- jquery;
- плагин для jquery
и подключим это всё дело. Но сначала надо создать форму для добавления статьи (фцк юзаю там и в новостях) с textarea
, на который, собственно, и будет вешаться фцк. А вешаться он будет следующим образом:function loadFck(e)
{
$('#'+e).fck({path: baseUrl+'/js/fckeditor/'});
}
Эта функция лежит в файле admin.js
(о чем ниже; так же, как и о baseUrl
), и ее надо будет вызвать в нужном месте. На вход приходит id текстэйрии (textarea), к которому будет приаттачен фцк.
Вот, собственно, и всё. Большинство примеров на этом и заканчиваются. Но всё же надо поподробней. Начать хотя бы с того, что мы юзаем jquery. И юзаем его хитро. With a little help from my friend (с) у меня есть замечательный вью хелпер jquery
, который неплохо бы подключить. Иничу я его так:protected function _initJquery()
{
$view = $this->getResource('view');
$view->jquery();
}
Но этого было недостаточно - нужно указать путь к вью хелперам. Поэтому также в буцтрапе я иничу и вью:protected function _initView()
{
if ($this->hasResource('view'))
$view = $this->getResource('view');
else
$view = new Zend_View();
$view->getHelper('BaseUrl')->setBaseUrl($this->getOption('baseurl'));
$view->setEncoding('UTF-8');
$view->addHelperPath('../application/views/helpers', 'Common_View_Helper');
return $view;
}
Интересно, что просто получить ресурс view
я не смог. Без проверки выдает ошибку. Поэтому на всякий случай проверка (рожденная коллективным разумом).
Итак, указали путь к плагину и - внимание - задали baseUrl
. Я наивно полагал, что он (бейзурл) определится сам. Но пришлось задать. $this->getOption('baseurl')
предательски получает переменную конфига ("логично", правда?). В конфиге у меня первой строчкой добавилось baseurl = "http://localhost/мой_проект/public"
. При этом при попытке написать имя переменной верблюжьимОбразом сей опшен был нулл. Что тоже "логично", правда?
А сей бейзурл мы указали для того, чтобы грузить джаваскрипты и цссы. Пока последних нету, так чтоprotected function _initHeadScript()
{
$view = $this->getResource('view');
$view->headScript()->prependScript('var baseUrl = "'.$view->baseUrl().'";')
->prependFile($view->baseUrl().'/js/jquery.js');
}
С помощью prependScript()
прописываем наш бейзурл для использования в наших джаваскриптовых манипуляциях. (Все эти _init*
- в буцтрапе.)
Теперь идем в Admin_ArticleController
:public function init()
{
$this->_model = new Admin_Model_Article();
if(in_array($this->getRequest()->getActionName(), array('add', 'edit'))) // loading fck only if need
{
$this->view->headScript()->appendFile($this->view->baseUrl().'/js/fckeditor/fckeditor.js')
->appendFile($this->view->baseUrl().'/js/jquery.FCKEditor.pack.js');
}
}
Ну тут вроде понятно - комментарий решает. Добавлю только, что второй файл - это плагин для jquery, а модель - приватнная переменная для использования при операциях с БД. Тут же, в addAction()
(а позже и в edit
) вызываем нашу самую первую функцию:public function addAction()
{
$form = new Admin_Form_Article();
$this->view->form = $form;
$fckText = $form->getElement('text')->getId();
$this->view->jquery("loadFck('{$fckText}')");
}
Интересные пироги приключились при попытке подключить admin.js
, в которой находится loadFck()
только для админского модуля (хотя, писуя сию строку, я подумал, что с нижеследующим можно было бы не заморачиваться, буде у нас файл default.js
). Вспомнил я внезапно про Admin_Bootstrap
- буцтрап модуля. Натурально, следует в нем подгрузить admin.js
с помощью _initHeadScript()
, аналогичной тому, что в дефолтном буцтрапе. Но вот беда: не нашелся хелпер headScript()
. Где-то я с подобным сталкивался, подумал я и вспомнил, как полчаса назад у меня не виделся хелпер baseUrl()
по причине отсутствия _initView()
. И застучали пальцы по клавишам...protected function _initView()
{
$view = $this->getApplication()->getResource('view');
return $view;
}
В этом ините нету ничего лишнего. Я даже выкинул из него setBaseUrl()
. К $this->getApplication()
я пришел опытным путем. Чтобы получить $view
, я создавал инстанс дефолтного бутстрапа и хотел из него что-то взять аж через конфиг... а, точно - я ж устанавливал бейзурл. Но конструктор бутстрапа хотел $application
, и получил $this->getApplication()
. После чего для меня стало очевидно, что создавать инстанс нет смысла, и можно обойтись просто $this->getApplication()
...
20 August, 2009
Мой опыт в создании модульного приложения на Zend Framework: Часть 5
Posted at 00:16 0 comments
19 August, 2009
Random and Instant
There are some places to go
And where they are I don't know
And if you ask me some time
I'd rather bring you some wine
Posted at 21:43 0 comments
16 August, 2009
Мой опыт в создании модульного приложения на Zend Framework: Часть 4
Подошла очередь форм.
Решил, что так, как писали мы раньше - создание формы в контроллере - некрасиво. Захотелось мне вынести формы в отдельную папочку forms
в руте модуля.
Первое, с чем приходится столкнуться, - номенклатура. Как помнится, у меня два модуля: default
и admin
. Соответственны и неймсппейсы. Т. е. в дефолтном модуле я создал уже ранее модель Default_Model_Feedback
в папке models
, а в админском - Admin_Model_User
в папке admin/models
. Аналогичным образом создаем и формы. Например, первая форма, которую я создал - форма логина Default_Form_Login
.
В начале меня вводило в ступор и непонимание то, что я не мог создать, например, файл forms/LoginForm.php
так, чтобы он увиделся аналогично контроллерам (ср. controllers/UserController.php
). Очевидно, таковое было обусловлено моим стремлением к перфекционизму: мне хотелось, чтобы всё было красиво, и сия пелена застилала мне глаза :) Однако, трезво взглянув на вещи, я вижу, что, пожалуй, я был не прав. Хотя вот что меня смутило. Согласно мануалу ZF, Zend_Application_Module_Autoloader, comes with the following mappings:
api/ => Api
forms/ => Form
models/ => Model
DbTable/ => Model_DbTable
plugins/ => Plugin
Т. е. выходит, что у нас будут, если будут, Default_Api_Foo
, Default_Plugin_Bar
etc.
Дальше. Создал я свой класс формы. В нем создаю конструктор, в который передаю $options = null
. Ну и внутри создаю форму, прежде вызвав конструктор предка:parent::__construct($options);
$this->setMethod('post')
->setAction('user/login')
->setName('loginForm');
$login = $this->createElement('text', 'login')
->setLabel('Логин');
$password = $this->createElement('password', 'password')
->setLabel('Пароль');
$submit = $this->createElement('submit', 'submit')
->setLabel('Войти');
$this->addElements(array($login, $password, $submit));
Внимание: конструктор ничего не возвращает! Вероятно, это логично, но я попался.
Posted at 19:00 0 comments
12 August, 2009
Мой опыт в создании модульного приложения на Zend Framework: Часть 3
Дошло дело и до аутентификации.
Сначала - ACL (access control level). Создал файл Spod_Acl
(в своем "подразделении" библиотеки), в нем прописал роли и ресурсы, а тж. allow
и deny
. Здесь всё.
Затем - Auth. Свой, по аналогии, Spod_Auth
, как мы писали ранее и я не совсем понимал, я не писал. Точнее, не писал по тому принципу, по которому он сделан в одной из статей на девзоне. Я создал класс Spod_Authenticator
, в котором, с позволения сказать, перегрузил метод класса Zend_Auth_Adapter_DbTable authenticate()
- просто для того, чтобы было проще. Т. к. в "свой" authenticate()
я поместил вызов и обработку "того", родного зендовского метода аутентификации:public function authenticate($login, $password)
{
$authAdapter = new Zend_Auth_Adapter_DbTable($this->_dbAdapter, $this->_dbTable, $this->_identityColumn, $this->_credentialColumn, 'MD5(?)');
$authAdapter->setIdentity($login);
$authAdapter->setCredential($password);
return $this->_auth->authenticate($authAdapter);
}
Как видим, параметры - логин и пароль (мы ж аутентификацию пишем). А методы класса проиничены в конструкторе. В итоге вызывать надо так:$sAuth = new Spod_Authenticator('users', 'us_login', 'us_pass');
$result = $sAuth->authenticate($login, $password);
Долго думал и страдал над ошибкой "No adapter found..." - точно не вспомню формулировку, но суть в том, что для Zend_Auth_Adapter_DbTable
нужен наш адаптер к базюке. Конфиг адаптера - в апп.ини. Казалось бы, взять и вытащить по аналогии с другими ресурсами бутстрапа, типа $view = $this->getResource('view');
. Я так и пытался. NULL
, и хоть ты тресни... В итоге выцепил из старых проектов фактори конфига, получение из него db
(натурально, этот самый адаптер пихаю в реестр и в конструкторе своего аутентификатора получаю). Так и сделал. Занялся следующей частью проекта... как тут случайно и внезапно наскочил в доке на то, что db
и его адаптер надо получать так:$resource = $bootstrap->getPluginResource('db');
$db = $resource->getDbAdapter();
Posted at 20:44 0 comments
02 August, 2009
Мой опыт в создании модульного приложения на Zend Framework: Часть 2
Вторая часть задачи.
В моем проекте должен быть, как я уже писал, админский модуль; а вот фронт-энд должен быть разделен на две одинаковые по структуре части. Первоначально я думал сделать для каждой из них свой отдельный модуль. Но ведь структура один в один, и я решил, что это неразумно. И тут мне на помощь вновь пришел Ероен Кеппенс! Похоже, я торчу ему пиво...
В своей другой статье он рассказал, как он сделал админский псевдо-модуль - "попросту" попрописывал руты. Я немного видоизменил его код, убрав из рутов :module
- я не понял, зачем ему надо было его указывать - на мой взгляд, по крайней мере, в моем проекте, это кажется излишеством. Таким образом, у меня получилось три, а не четыре, рута. Кроме того, в конструктор Zend_Controller_Router_Route
я не добавлял _layout
- учитывая LayoutLoader
в первой части (я, Ероен), я решил, что это лишнее. Вместо этого я написал роутеру, что мой псевдомодуль - на самом деле дефолтный модуль. Но также, чтобы различать, в каком псевдомодуле я нахожусь, там же прописал и переменную, которая видна в getRequest()
.
В итоге получилось:$route = new Zend_Controller_Router_Route(
'ophtalmology/:controller/:action/*',
array('module' => 'default', 'section' => 'ophtalmology'));
$front->getRouter()->addRoute('ophtalmology_controller_action', $route);
и далее по тексту.
Posted at 14:12 0 comments
Labels: modular, zend framework, zend_router
Мой опыт в создании модульного приложения на Zend Framework: Часть 1
Решил сделать все "правильно". Пишу, чтобы запомнились шаги - что-то типа self-manual...
Итак, упрощенная задача: приложение с двумя модулями - дефолтным и админским.
Естественно, сперва скачал последний фреймвёрк.
Затем создал системную переменную zf
и в нее поместил путь к zf.bat
(Zend Framework/bin/zf.bat
).
Потом из командной строки командой zf create project
создал проект. При этом вызывал из папки, в которой следовало создать проект, но почему-то тул попросил указать путь к проекту.
Не забыл скопировать библиотеку в мой_проект/library
.
Дальше пошел гуглить :) Т. к. интересовало, как люди создают модульные проекты. В принципе, некий опыт был, но он, на мой взгляд, был каким-то... не совсем правильным.
Нашел статью некого Ероена Кеппенса, который очень мне помогает (начальное написание проекта все еще в процессе) - вот она.
До момента написания LayoutHelper
сделал, в общем-то, всё, как и у него:
- zf create module admin
;
- добавил в application.ini
строкиresources.frontController.moduleDirectory = APPLICATION_PATH "/modules"
resources.modules[]
За исключением того, что не добавил буцтрап в админский модуль и пока еще не проинитил в буцтрапе приложения _initAppAutoload()
- т. к. мне непонятно, почему здесь мы видим App
- в квикстарте никакого App
нету... будем посмотреть.
Дальше создал папку application/views/layouts
, в нее поместил default.phtml
и admin.phtml
- лэяуты для дефолтного и админского модулей соответственно.
Дальше, как и у мистера Кеппенса, добавил в конфиг следующее:resources.layout.layoutPath = APPLICATION_PATH "/views/layouts"
resources.layout.layout = default
admin.resources.layout.layout = admin
А вот потом, несколько подумав, решил таки воспользоваться его хелпером для подгрузки лэяутов. Долго думал, куда же мне положить этот хелпер - у автора он лежит в его собственной лайбрари, но в предыдущих проектах мы клали экшен хелперыы прямо в approot, что мне кажется не совсем правильным - грубо говоря, засирается папка, да и как-то не по-зендовски это. В итоге, было решено в папке мой_проект/library
создать папку для, так сказать, собственной библиотеки: мой_проект/library/Spod
. И хелпер поместил по пути, аналогичному тому, где лежат экшен хелперы в родной зендовской библиотеке, предварительно, естественно, посоздавав соответствующие папки: мой_проект/library/Spod/Controller/Action/Helper/LayoutLoader.php
.
Ну и проинитил в буцтрапе, как и автор.
После этого, обновив страничку, обнаружил ошибку, что мой класс не найден. Вспомнил, что автор в начале статьи прописал свою библиотеку в конфиг. Так же сделал и я:autoloaderNamespaces.spod = "Spod_"
Работает so far :)
Posted at 13:22 0 comments
Labels: modular, zend framework, zend tool, zend_layout