Январь 9, 2012 | ITшное, код | Модные словечки poedit, translate, zf, локализация | Оставить свое мнение
Одним из самых удобных способов локализации приложения, по моему мнению, является использование po/mo файлов с переводами, которые генерирует допотопная программа poedit, лучшей к сожалениею не написали :-(
Так вот, если вы прописали правильно пути к базе файлов которые нужно сканировать, ключевые слова выставлены верно, но программа не находит слова, которые находятся скажем в файлах с расширением отличных от стандартных (пример: php контент в файле *.phtml, что свойственно шаблонам вида в ZF).
Нашел вот здесь: http://web-blog.org.ua/articles/zend-framework-localizatsiya-proektov-chast-tretyaya хорошее описание и решение проблеммы. На всяк случай продублирую вкратце и у себя:
- Файл — Установки — Парсеры — PHP — Править
- изменяем строку с расширениями на эту: *.php;*.phtml
- изменяем строку с командой вызова на эту: xgettext —language=PHP —force-po -o %o %C %K %F
Подробнее в блоге по ссылке выше.
Декабрь 20, 2011 | ITшное, код | Модные словечки php, zf | Оставить свое мнение
Если вам нужно будет разделить проект на две части: ядро и кастом (например если многие части кода используются для нескольких проектов), то одним из вариантов решения такой задачи будет использовать ядро как и раньше, а все что отличается веносить в папки типа Project_custom/application|configs|models и так далее.
Так же важно что бы файлы подключались сразу из cutom папки, и только если не находились там, то брались с ядра.
Для моделей это легко делается правильной настройкой аутолоадера, а точнее даже просто прописать include_paths в правильном порядке.
А вот с контроллерами было сложнее. В конфиге одному модулю можно задать только один путь. А вешать кастомные контроллеры на отдельный модуль в итоге не давало бы возможности перезаписывать стандартные контроллеры.
В общем по итогу у меня родился такой вот изящный результат. Пишем плагин.
class Plugin_CustomController extends Zend_Controller_Plugin_Abstract
{
public function preDispatch(Zend_Controller_Request_Abstract $request)
{
$front = Zend_Controller_Front::getInstance();
$dispatcher = $front->getDispatcher();
// здесь указываем путь к кастом контроллерам
$dispatcher->setControllerDirectory(APPLICATION_CUSTOM_PATH.’/controllers’);
if (!$dispatcher->isDispatchable($request))
$dispatcher->setControllerDirectory(APPLICATION_PATH.’/controllers’); // а здесь контроллеры ядра
}
}
И в бутстрапе подключаем плагин:
Zend_Controller_Front::getInstance()->registerPlugin(new Plugin_CustomController());
Так же еще сходу не знал как сделать возможность перебивания layout-ов, но для них все оказалось еще проще — просто в конфиге проекта указать следующее:
‘resources’ => array(
‘layout’ => array(‘layoutPath’ => array(APPLICATION_PATH.’/layouts/scripts/’, APPLICATION_CUSTOM_PATH.’/layouts/’)),
)
При чем что важно, подключаться файлы будут в порядке, обратном указанном.
Так само указывается путь для подключения скриптов вида:
array(‘resources’ => array(
‘view’ => array(
‘scriptPath’ => array(APPLICATION_PATH.’/views/scripts/’,APPLICATION_CUSTOM_PATH.’/views/scripts/’),
));
UPD: как оказалось, переделать автозагрузчик оказалось не тривиальной задачей. Не буду писать всего, скажу как в итоге сделать правильно. Код правда здесь приводить не могу.
- создать один массив resourceTypes с описанием неймспейсов и путей к папкам нужным;
- создать два Zend_Loader_Autoloader_Resource в первом путь basePath задать к кастомной части, во втором к core файлам, resourceTypes в этих автозагрузчиках поставить одинаковым;
- для Zend_Loader_Autoloader сделать поочередно pushAutoloader сначала для кастом части, а затем для ядра;
- правильность подключения файлов без заковыристых namespace-ов обеспечивается указанием includePaths в правильной последовательности: сначала путь к кастом части, затем к ядру.
Note: не забудьте убрать затем все include/require — это поломает логику правильных автолоадов файлов =)
Июнь 16, 2011 | ITшное | Модные словечки zf, код, тонкости | Оставить свое мнение
Если возникает задача использовать классы без неймспейсов( например Stat, Config и т.п. — без неймспейса, Model_Stat, Custom_Logger — с неймспейсами), то в ZF это вызовет трудности.
В результате копания кода найдено такое решение:
$autoloader->registerNamespace($namespaces)
->pushAutoloader($autoloader->getDefaultAutoloader(), ») // add loader for non namespaced classes
->pushAutoloader($resourceLoader, $namespaces);
Здесь «->pushAutoloader($autoloader->getDefaultAutoloader(), »)» регистрирует пустой неймспейс и а ниже регистрируются заполненные неймспейсы.
Если к примеру пустой неймспейс указать просто как пустое значение в перечислении конфига неймспейсов, будет ошибка.
Такой день.
Апрель 30, 2011 | ITшное, код | Модные словечки zf, баги, конфиг, ошибки | Оставить свое мнение
Продолжаю серию увлекательных особенностей ZF и PHP в общем.
Итак, если по неизвестной закономерности у вас возникает ошибка Access to undeclared static property: Zend_Loader_Autoloader::$_instance или же происходит фатал эррор с ошибкой «обращение к несуществующей переменной», а в коде это выглядит типа как self::MYCONST то эта запись для вас.
В общем написал я недавно класс Zend_Session_SaveHandler_Memcached что бы использовать его как сторэдж для сохранения сессий.
И поначалу вроде как все работало нормально, но потом по неизвестной закономерности начала появляться ошибка что скрипт обращается к несуществующей переменной. Естественно, константа в классе объявлена. Замена self на Zend_Session_SaveHandler_Memcached результата не дало, ровно как и обновление пхп со всеми модулями. При это еще после того как скрипт меняется, страница грузится нормально, без ошибок, а последующие загрузки вызывают эту ошибку.
И еще более загадочно, без установленной закономерности, раз на сколько то вызовов появляется ошибка, озвученная выше.
В итоге установил что проблема в параметре apc.cache_by_default который задается в php.ini и который был включен на этом сервере, а на других (на которых и ошибки этой не было) данного парамера пхпинфо вообще не возвращал. Установка параметра в 0 соответственно решило проблему.
Такой день.
Апрель 30, 2011 | ITшное, код | Модные словечки soap, zf | Оставить свое мнение
Нынче закончил работу над API сервером на SOAP и опишу еще один момент, с которым возможно столкнется еще кто-то.
Итак, в Zf работа Soap сервера основана на двух элементах — autoDiscover и собственно soap_server. Оба этих элемента расположены на сервере и ссылаются друг на друга. И вот особенность в том, что при получении запроса на выполнение функции от соап клиента просходит запрос с soap_server на autoDiscover (адреса одного и другого указываются в самом сервере). Проблема, из-за которой пришлось потратить около часа на поиск решения проблемы была в том, что соап клиент возвращал:
Fatal error: Uncaught SoapFault exception: [WSDL] SOAP-ERROR: Parsing WSDL: Couldn’t load from ‘https://[censored]‘ : failed to load external entity [url]
Сразу просто не догадался искать проблему на сервере, т.к. ошибку то возвращает клиент. Но как оказалось, он просто перетранслирует ошибку, которую возвращает сервер. А сервер ругался из-за того, что php был без модуля openssl. В общем в итоге доставление php5-openssl решило проблему.
Последние отзывы