Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony 2 project in nested directory

Tags:

php

symfony

I need to deploy a Symfony 2 project in nested directory on production server. Effectively, this would mean that all URLs are prefixed with /subdirectory/ path, i.e.

http://host.com/subdirectory/project/web/app.php/survey

I don't need URL rewriting and are am not going to set it up. The app should work when accessed via above URL only.

The problem I have is that all links generated by path and asset Twig functions are relative to server root (/), and not subdirectory the project is in (/subdirectory/). Is there any config parameter in Symfony 2 to override relative paths globally?

I tried to work around that problem by adding HTML tag, but it doesn't work for links.

Update: I owe you further details. I'm running IIS with its version of mod_rewrite, so part of your suggestions may still be valid.

Update: Ideally I would like to see a solution that sets root dir on AppKernel object - method AppKernel::setRootDir() had it existed to complement existing AppKernel::getRootDir().

like image 256
Michał Niedźwiedzki Avatar asked Sep 10 '13 09:09

Michał Niedźwiedzki


2 Answers

Strange... with default config, path/asset should handle subdirectories. Have you tried it with symfony distribution out-of-the-box? On localhost im mostly using it this way. Would you mind posting your config file?

Anyway... For assets paths you could try to configure:

#config.yml
templating:
  assets_base_urls: { http: "http://yoursite.com/dir1", ssl: "https://yoursite.com/dir1" }

(http://symfony.com/doc/current/reference/configuration/framework.html#assets-base-urls)

For router you should read: http://symfony.com/doc/current/cookbook/console/sending_emails.html#configuring-the-request-context-globally It could give you some ideas about changing router context like:

# app/config/parameters.yml
parameters:
  router.request_context.host: example.org
  router.request_context.scheme: http
  router.request_context.base_url: my/path

Anyway - context is automaticlly set based on request information. Try to debug:

$context = $this->getContainer()->get('router')->getContext();
// you should be mainly interested in:
$context->getBaseUrl();

It is possible to easily create listener class which will manually set your base url if anyhow it is wrong:

class RouterContextListener {

    protected $router;

    public function __construct(RouterInterface $router)
    {
        $this->router = $router;
    }

    public function onKernelRequest(Event $event)
    {
        $this->router->setBaseUrl('somedir');
    }
}
like image 107
Antoni Orfin Avatar answered Oct 10 '22 16:10

Antoni Orfin


You are looking for RewriteBase rule, add it to your in your .htaccess:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /subdirectory/project/web
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ app.php [QSA,L] 
</IfModule>

Also take a look onto symfony-standard 2.3 .htaccess file, mb it can help

<IfModule mod_rewrite.c>
    RewriteEngine On

    RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$
    RewriteRule ^(.*) - [E=BASE:%1]

    RewriteCond %{ENV:REDIRECT_STATUS} ^$
    RewriteRule ^app\.php(/(.*)|$) %{ENV:BASE}/$2 [R=301,L]

    # If the requested filename exists, simply serve it.
    # We only want to let Apache serve files and not directories.
    RewriteCond %{REQUEST_FILENAME} -f
    RewriteRule .? - [L]

    # Rewrite all other queries to the front controller.
    RewriteRule .? %{ENV:BASE}/app.php [L]
</IfModule>
like image 25
Alexey B. Avatar answered Oct 10 '22 16:10

Alexey B.