Zend Framework: разделение проекта на Core-Custom
Декабрь 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 — это поломает логику правильных автолоадов файлов =)
Наследить..