Честно говоря, вы не получите полного контроля над структурой проекта на symfony, прочитав этот пост. На его написание меня подтолкнула ситуация на работе. Клиент поставил условие, что по завершению разработки проект должен быть развернут на его хостинге. Все бы ничего, но вот ftp заказчик согласился дать лишь к document root'у сайта, а также к еще одной папке, находящейся на одном уровне с ним. Естественно, в таком случае, развернуть проект на symfony без танцев с бубном вряд ли получится. Долго я серфил инет в поисках решения, но так и не нашел его.

Задача

Нужно разместить проект в двух папках на одном уровне (хотя их положение относительно друг друга неважно), причем одна из папок – это document root сайта. Смешно, но решение оказалось очень простым.

<?php

/*
Файл /config/ProjectConfiguration.class.php
должен выглядеть приблизительно так.
*/

require_once dirname(__FILE__).'/../lib/symfony/autoload/sfCoreAutoload.class.php';
sfCoreAutoload::register();

class ProjectConfiguration extends sfProjectConfiguration {
...

Естественно, для такого проекта можно использовать как standalone библиотеки, так и отдельно установленные через PEAR. Просто нужно указать правильный относительный путь к автолоадеру ядра.
Следующим шагом будет исправление входных точек приложений в папке /web. Рассмотрим пример с index.php.

<?php

//	Исходный файл /web/index.php

require_once(dirname(__FILE__).'/../config/ProjectConfiguration.class.php');

$configuration = ProjectConfiguration::getApplicationConfiguration('frontend', 'prod', false);
sfContext::createInstance($configuration)->dispatch();

Нам нужно указать путь к конфигурационному файлу в строке 8, учитывая, что все папки проекта, кроме /web, будут находятся во второй директории, к которой у нас есть ftp-доступ.

Получаем приблизительно следующее

<?php

//	Файл /web/index.php

require_once(dirname(__FILE__).'/../data/config/ProjectConfiguration.class.php');

$configuration = ProjectConfiguration::getApplicationConfiguration('frontend', 'prod', false);
sfContext::createInstance($configuration)->dispatch();

В данном примере вспомогательным каталогом является каталог data. Таким же образом меняем другие входные точки, вроде frontend_dev.php, backend.php, backend_dev.php. Остается только раскидать проект по папкам. Всё, кроме папки /web, перемещаем в папку data. А содержимое папки /web кидаем в наш document root.
В принципе, это все. Можно по аналогии поменять файл symfony, по которому мы выполняем таски. Не факт, что все будет работать правильно. Например, plugin:publish-assets точно не будет. Но я не думаю, что на продакшене понадобится выполнение тасков, работающих с папкой /web.

UPD: для того чтобы заработали таски работающие с папкой /web, нужно поправить конфигурацию проекта.


// config/ProjectConfiguration.class.php
class ProjectConfiguration extends sfProjectConfiguration
{
  public function setup()
  {
    $this->setWebDir($this->getRootDir().'/../web');
  }
}

Спасибо Евгению и документации по symfony за упоминание об этом методе.