<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet title="XSL formatting" type="text/xsl" href="http://mirmodynamics.com/feed/rss2/xslt" ?><rss version="2.0"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:wfw="http://wellformedweb.org/CommentAPI/"
  xmlns:content="http://purl.org/rss/1.0/modules/content/"
  xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
  <title>Mirmo Dynamics - Tag - apache</title>
  <link>http://mirmodynamics.com/</link>
  <atom:link href="http://mirmodynamics.com/feed/tag/apache/rss2" rel="self" type="application/rss+xml"/>
  <description>Si tu kiffes pas reunoi, t'écoutes pas et puis c'est tout.</description>
  <language>en</language>
  <pubDate>Sun, 14 Mar 2010 19:59:01 +0100</pubDate>
  <copyright>2003-2009 &amp;copy; Geoffrey Bachelet</copyright>
  <docs>http://blogs.law.harvard.edu/tech/rss</docs>
  <generator>Dotclear</generator>
  
    
  <item>
    <title>Rewrite rule to add missing www</title>
    <link>http://mirmodynamics.com/post/2009/03/17/Rewrite-rule-to-add-missing-www</link>
    <guid isPermaLink="false">urn:md5:0bab59ade6517a990b75546554dba814</guid>
    <pubDate>Tue, 17 Mar 2009 19:30:00 +0100</pubDate>
    <dc:creator>Geoffrey</dc:creator>
        <category>Geekeries</category>
        <category>apache</category><category>mod_rewrite</category><category>rewritecond</category><category>rewriterule</category>    
    <description>    &lt;pre&gt;
  RewriteEngine on
  RewriteCond %{SERVER_NAME} !^www\..*$
  RewriteRule ^/(.*)$ http://www.%{SERVER_NAME}/$1 [L,QSA,R=302]
&lt;/pre&gt;


&lt;p&gt;From &lt;a href=&quot;http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html#rewriterule&quot;&gt;the manual&lt;/a&gt;, using &lt;code&gt;%1&lt;/code&gt; as a back reference from the &lt;code&gt;RewriteCond&lt;/code&gt; in the &lt;code&gt;RewriteRule&lt;/code&gt; should work, but it didn't on my installation. Weird.&lt;/p&gt;</description>
    
    
    
          <comments>http://mirmodynamics.com/post/2009/03/17/Rewrite-rule-to-add-missing-www#comment-form</comments>
      <wfw:comment>http://mirmodynamics.com/post/2009/03/17/Rewrite-rule-to-add-missing-www#comment-form</wfw:comment>
      <wfw:commentRss>http://mirmodynamics.com/feed/atom/comments/1183</wfw:commentRss>
      </item>
    
  <item>
    <title>Multiple domains for one symfony project, the basics</title>
    <link>http://mirmodynamics.com/post/2008/12/22/Multiple-domains-for-one-symfony-project%2C-the-basics</link>
    <guid isPermaLink="false">urn:md5:9fbb9dbd582af2cc7fb3a7b9f201cd6a</guid>
    <pubDate>Mon, 29 Dec 2008 11:10:00 +0100</pubDate>
    <dc:creator>Geoffrey</dc:creator>
        <category>Symfony</category>
        <category>apache</category><category>carshop</category><category>dispatcher</category><category>doctrine</category><category>howto</category><category>mod_rewrite</category><category>multidomain</category><category>symfony</category>    
    <description>    &lt;p&gt;So let's say you run a car franchise, and you have several shops that you want to be able to manage through a web application. The application would be same for each shop, except you'd have to manage different sets of data and have specific assets for each shop. Fear not, this is very easy to achieve using symfony (well, it's quite easy with any framework I guess, but we will be using symfony :p)&lt;/p&gt;


&lt;h3&gt;Sample project&lt;/h3&gt;


&lt;p&gt;At the beginning, there were &lt;code&gt;generate:project&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;
$ mkdir carshop
$ cd carshop
$ symfony generate:project carshop
$ symfony generate:app frontend
$ symfony generate:module frontend default
&lt;/pre&gt;


&lt;p&gt;We will also need a simple database schema for the sake of examples. We will be using Doctrine, so let's fill in our &lt;code&gt;config/doctrine/schema.yml&lt;/code&gt; with a very simple schema:&lt;/p&gt;

&lt;pre&gt;
[yml]
detect_relations: true

Car:
  columns:
    site_id:      { type: integer }
    name:         { type: string(255) }
    description:  { type: clob }
    image:        { type: string(255) }

Site:
  columns:
    name:         { type: string(255) }
    domain:       { type: string(255), unique: true }
    main:           { type: boolean, default: false }
&lt;/pre&gt;


&lt;p&gt;Also, let's not forget to enable Doctrine in our project in &lt;code&gt;config/ProjectConfiguration.class.php&lt;/code&gt;, replace the line:&lt;/p&gt;

&lt;pre&gt;
[php]
$this-&amp;gt;enableAllPluginsExcept('sfDoctrinePlugin');
&lt;/pre&gt;


&lt;p&gt;with:&lt;/p&gt;

&lt;pre&gt;
[php]
$this-&amp;gt;enableAllPluginsExcept('sfPropelPlugin');
&lt;/pre&gt;


&lt;p&gt;and to configure the database:&lt;/p&gt;

&lt;pre&gt;
$ symfony configure:database --name=doctrine --class=sfDoctrineDatabase &amp;quot;mysql:host=localhost;dbname=carshop&amp;quot; root
&lt;/pre&gt;


&lt;p&gt;Oh, we shall need some fixtures too, let's put them in &lt;code&gt;data/fixtures/01_sites.yml&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;
[yml]
Site:
  paris:
    name: Paris
    domain: paris.carshop
  auckland:
    name: Auckland
    domain: auckland.carshop
&lt;/pre&gt;


&lt;p&gt;and &lt;code&gt;data/fixtures/02_cars.yml&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;
[yml]
Car:
  car_1:
    Site: paris
    name: Peugeot 307
    description: Lorem ipsum dolor sit amet, consectetur adipiscing elit.
  car_2:
    Site: paris
    name: Renault Laguna
    description: Maecenas tortor nunc, aliquam et, ultrices id, ornare consectetur, mauris.
  car_3:
    Site: auckland
    name: Subaru Impreza
    description: Ut accumsan diam et orci. Sed sit amet neque ac diam rutrum iaculis.
&lt;/pre&gt;


&lt;p&gt;And now that everything is ready, let's create the tables and load the fixtures:&lt;/p&gt;

&lt;pre&gt;
$ symfony doctrine:build-all-load
&lt;/pre&gt;


&lt;h4&gt;Vhosts&lt;/h4&gt;


&lt;p&gt;The second thing we will need is a set of vhost with differents domains all pointing to our newly generated project. It's quite easy to do, and I will assume you run some kind of linux or unix here (although it's similar under windows if I remember well). Let's start with creating fake domain names, you just have to add the following line to your &lt;code&gt;/etc/hosts&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;
127.0.0.1 auckland.carshop paris.carshop
&lt;/pre&gt;


&lt;p&gt;And the following to your apache vhost:&lt;/p&gt;

&lt;pre&gt;
[apache]
ServerName paris.carshop
ServerAlias *.carshop
&lt;/pre&gt;


&lt;p&gt;Save and quit, reload apache, and you're all set.&lt;/p&gt;


&lt;h3&gt;Detecting the current site&lt;/h3&gt;


&lt;p&gt;First thing we need to know if we want to handle site-specific data, is which site we're currently in. This can easily be done in the project configuration. Since we will need database access, we will hook up on the &lt;code&gt;context.load_factories&lt;/code&gt; event. So, on with coding, open your &lt;code&gt;config/ProjectConfiguration.class.php&lt;/code&gt; and add the following line to the &lt;code&gt;setup()&lt;/code&gt; method:&lt;/p&gt;

&lt;pre&gt;
[php]
$this-&amp;gt;dispatcher-&amp;gt;connect('context.load_factories', array($this, 'detectSite'));
&lt;/pre&gt;


&lt;p&gt;This will hook the &lt;code&gt;detectSite()&lt;/code&gt; method to the event &lt;code&gt;context.load_factories&lt;/code&gt;. We now need to add the &lt;code&gt;detectSite()&lt;/code&gt; method to the &lt;code&gt;ProjectConfiguration&lt;/code&gt; class:&lt;/p&gt;

&lt;pre&gt;
[php]
/**
 * Detects the current site based on the url
 * Fallback to the main site (main = 1 in database) if we can't find a suitable entry
 *
 * @param sfEvent $event
 */

public function detectSite(sfEvent $event)
{
  $request = sfContext::getInstance()-&amp;gt;getRequest();
  $domain = $request-&amp;gt;getHost();

  $siteTable = Doctrine::getTable('Site');

  if (false !== $site = $siteTable-&amp;gt;retrieveByDomain($domain))
  {
    $siteTable-&amp;gt;setCurrent($site);
  }
  else
  {
    $siteTable-&amp;gt;setCurrent($siteTable-&amp;gt;retrieveMain());
  }
}
&lt;/pre&gt;


&lt;p&gt;Nothing very hard here. We get the HTTP host from the request, then try to fetch a corresponding Site from the database, fallbacking to the main site if necessary. You may have noticed that we added three methods to the &lt;code&gt;Site&lt;/code&gt; model class: &lt;code&gt;retrieveByDomain()&lt;/code&gt;, &lt;code&gt;retrieveMain()&lt;/code&gt; and &lt;code&gt;setCurrent()&lt;/code&gt;. Your &lt;code&gt;lib/model/doctrine/SiteTable.class.php&lt;/code&gt; should look like this now:&lt;/p&gt;

&lt;pre&gt;
[php]
&amp;lt;?php
/**
 * This class has been auto-generated by the Doctrine ORM Framework
 */
class SiteTable extends Doctrine_Table
{

  /**
   * Holds the current site
   * @var Site
   */

  protected $current;

  /**
   * Retrieve a Site by its domain
   *
   * @param string $domain
   * @return Site or false if no site is found
   */

  public function retrieveByDomain($domain)
  {
    return $this-&amp;gt;createQuery()-&amp;gt;where('domain = ?', $domain)-&amp;gt;fetchOne();
  }

  /**
   * Retrieve the main site
   *
   * @return Site or false if no site is found
   */

  public function retrieveMain()
  {
    return $this-&amp;gt;createQuery()-&amp;gt;where('main = 1')-&amp;gt;fetchOne();
  }
  

  /**
   * Sets the current site
   *
   * @param Site $site
   */

  public function setCurrent(Site $site)
  {
    $this-&amp;gt;current = $site;
  }

}
&lt;/pre&gt;


&lt;p&gt;While we're there, let's add a &lt;code&gt;getCurrent()&lt;/code&gt; method as well:&lt;/p&gt;

&lt;pre&gt;
[php]
/**
 * Gets the current site
 *
 * @return Site
 */

public function getCurrent()
{
  return $this-&amp;gt;current;
}
&lt;/pre&gt;



&lt;h3&gt;Handling domain-specific logic and data&lt;/h3&gt;


&lt;p&gt;Ok, so now that we know where we are, let's make the Car model aware of the current site. Open &lt;code&gt;lib/model/doctrine/CarTable.class.php&lt;/code&gt; and add the &lt;code&gt;createQuery()&lt;/code&gt; method:&lt;/p&gt;

&lt;pre&gt;
[php]
/**
 * Creates a query, adding the site criteria automatically
 *
 * @return Doctrine_Query
 * @see Doctrine_Table::createQuery()
 */

public function createQuery($alias = '')
{
  $query = parent::createQuery($alias);
  $query-&amp;gt;where('site_id = ?', Doctrine::getTable('Site')-&amp;gt;getCurrent()-&amp;gt;getId());
  
  return $query;
}
&lt;/pre&gt;


&lt;p&gt;This is the method used internally by &lt;code&gt;Doctrine_Table&lt;/code&gt; to create queries related to the Car model, so now, all &lt;code&gt;find&lt;/code&gt; methods fired from the Car model will only fetch cars from the current site. We need to take care of this at &lt;code&gt;save()&lt;/code&gt; time too, in &lt;code&gt;lib/model/doctrine/Car.class.php&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;
[php]
/**
 * Automatically populates the site_id field if necessary
 * 
 * @see sfDoctrineRecord::save()
 */

public function save(Doctrine_Connection $conn = null)
{
  if (empty($this-&amp;gt;site_id))
  {
    $this-&amp;gt;setSite(Doctrine::getTable('Site')-&amp;gt;getCurrent());
  }

  return parent::save();
}
&lt;/pre&gt;


&lt;h3&gt;Handling domain specific assets&lt;/h3&gt;


&lt;p&gt;On with the assets. We are going to use our good friend &lt;code&gt;mod_rewrite&lt;/code&gt; to handle this. First, let's create a specific directory for each domain we're going to manage:&lt;/p&gt;

&lt;pre&gt;
$ mkdir -p web/perhost/{paris,auckland}.carshop/{css,images,js,uploads}
&lt;/pre&gt;


&lt;p&gt;Also, for testing purpose, let's create some fake js file:&lt;/p&gt;

&lt;pre&gt;
$ echo 'paris.carshop' &amp;gt; web/perhost/paris.carshop/js/foo.js
$ echo 'auckland.carshop' &amp;gt; web/perhost/auckland.carshop/js/foo.js
$ echo 'fallback' &amp;gt; web/js/fallback.js
&lt;/pre&gt;


&lt;p&gt;Then add some voodoo magic in your &lt;code&gt;web/.htaccess&lt;/code&gt;, before the &lt;em&gt;we skip all files with .something&lt;/em&gt; rules generated by symfony:&lt;/p&gt;

&lt;pre&gt;
[apache]
RewriteCond /home/ash/projects/carshop/trunk/web/perhost/%{HTTP_HOST}%{REQUEST_FILENAME} -f
RewriteRule (.*) /perhost/%{HTTP_HOST}/$1 [L]
&lt;/pre&gt;


&lt;p&gt;Please note that &lt;code&gt;%{REQUEST_FILENAME}&lt;/code&gt; includes the starting &lt;code&gt;/&lt;/code&gt;, so that we don't need to add one after &lt;code&gt;%{HTTP_HOST}&lt;/code&gt;.&lt;/p&gt;


&lt;p&gt;Now check that you have &lt;code&gt;mod_rewrite&lt;/code&gt; enabled (for example check that &lt;code&gt;/etc/apache2/mods-enable/rewrite.load&lt;/code&gt; exists). If it's not enabled it, do it now:&lt;/p&gt;

&lt;pre&gt;
$ sudo a2enmod rewrite
$ sudo /etc/init.d/apache2 reload
&lt;/pre&gt;


&lt;p&gt;You can test the following urls to see if everything is going well, the results should be pretty obvious:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://paris.carshop/js/foo.js&quot; title=&quot;http://paris.carshop/js/foo.js&quot;&gt;http://paris.carshop/js/foo.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://auckland.carshop/js/foo.js&quot; title=&quot;http://auckland.carshop/js/foo.js&quot;&gt;http://auckland.carshop/js/foo.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://paris.carshop/js/fallback.js&quot; title=&quot;http://paris.carshop/js/fallback.js&quot;&gt;http://paris.carshop/js/fallback.js&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;See you next time !&lt;/h3&gt;


&lt;p&gt;Now you have a working multi-domain architecture for your symfony project, but there are still a couple of things we could (and will) discuss:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;uploading assets (from forms for example)&lt;/li&gt;
&lt;li&gt;having a different layout for each site&lt;/li&gt;
&lt;li&gt;having specific css files for each site (eg: paris.css and auckland.css)&lt;/li&gt;
&lt;li&gt;cache problematic for shared assets&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All these points will be addressed in the next part of this tutorial, but not before 2009 has came !&lt;/p&gt;</description>
    
    
    
          <comments>http://mirmodynamics.com/post/2008/12/22/Multiple-domains-for-one-symfony-project%2C-the-basics#comment-form</comments>
      <wfw:comment>http://mirmodynamics.com/post/2008/12/22/Multiple-domains-for-one-symfony-project%2C-the-basics#comment-form</wfw:comment>
      <wfw:commentRss>http://mirmodynamics.com/feed/atom/comments/1163</wfw:commentRss>
      </item>
    
  <item>
    <title>Apache and mod_rewrite to subdirectories</title>
    <link>http://mirmodynamics.com/post/2008/06/26/Apache-and-mod_rewrite-to-subdirectories</link>
    <guid isPermaLink="false">urn:md5:e1fd6a0a067fd54399d7439b28f06814</guid>
    <pubDate>Thu, 26 Jun 2008 18:17:00 +0200</pubDate>
    <dc:creator>Geoffrey</dc:creator>
        <category>Geekeries</category>
        <category>apache</category><category>mod_rewrite</category><category>naneau</category>    
    <description>    &lt;p&gt;&lt;a href=&quot;http://naneau.nl&quot;&gt;Naneau&lt;/a&gt; just poke me with a little problem he had with &lt;a href=&quot;http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html&quot;&gt;mod_rewrite&lt;/a&gt; when trying to rewrite to a subdirectory. Imagine you've got the following setup:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Apache's document root is /document_root/&lt;/li&gt;
&lt;li&gt;You application's bootstrap is /document_root/public/index.php&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You could come to the following rewrite rules quite easily:&lt;/p&gt;

&lt;pre&gt;
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ public/index.php/$1 [L]
&lt;/pre&gt;


&lt;p&gt;And you'd be horribly wrong.&lt;/p&gt;


&lt;p&gt;The problem here is that when you hit &lt;code&gt;/&lt;/code&gt; on your server, mod_rewrite will populate &lt;code&gt;%{REQUEST_FILENAME}&lt;/code&gt; it to &lt;code&gt;/document_root/&lt;/code&gt;, which obviously fails the &lt;code&gt;!-d&lt;/code&gt; rewrite condition. By the magic of &lt;code&gt;DirectoryIndex&lt;/code&gt;, you'll eventually hit &lt;code&gt;/index.html&lt;/code&gt; (or whatever your directory index is set to), and there we go for another rewrite magic. At this point, things get a little messy, and if you're like naneau, you'll end up crying while rolling on the floor and calling for help on irc (that's quite a set of hard things to achieve at the same time).&lt;/p&gt;


&lt;p&gt;The solution is not that simple, and actually, I've not found a fully satisfying solution yet (although naneau is satisfied with the partial solution). The quick hack is to simpy remove the &lt;code&gt;!-d&lt;/code&gt; condition. The obvious drawback is that any existing directory &lt;strong&gt;will&lt;/strong&gt; get rewritten, but you'll be able to access the files inside it. I'm still working on a more complete solution, but as it's not my main concerne for the moment, it'll wait a bit (unless someone posts a solution in the comments).&lt;/p&gt;</description>
    
    
    
          <comments>http://mirmodynamics.com/post/2008/06/26/Apache-and-mod_rewrite-to-subdirectories#comment-form</comments>
      <wfw:comment>http://mirmodynamics.com/post/2008/06/26/Apache-and-mod_rewrite-to-subdirectories#comment-form</wfw:comment>
      <wfw:commentRss>http://mirmodynamics.com/feed/atom/comments/1107</wfw:commentRss>
      </item>
    
  <item>
    <title>Edgy Eft, Dotdeb, php5-pdo-mysql, et moi</title>
    <link>http://mirmodynamics.com/post/2006/10/01/Edgy-Eft-Dotdeb-php5-pdo-mysql-et-moi</link>
    <guid isPermaLink="false">urn:md5:cada8260083979d00e67ac977cd4ac6b</guid>
    <pubDate>Sun, 01 Oct 2006 04:25:00 +0200</pubDate>
    <dc:creator>Geoffrey</dc:creator>
        <category>Geekeries</category>
        <category>apache</category><category>apt</category><category>dotdeb</category><category>php</category><category>ubuntu</category>    
    <description>    &lt;p&gt;Bon voilà, ce n'est un secret pour personne, j'ai mis à jour ma Dapper en Edgy, et après avoir laborieusement activé l'accélération &lt;acronym&gt;3D&lt;/acronym&gt; de ma carte graphique, je me suis attelé à la reconstitution de mon environnement de développement favori: &lt;acronym&gt;LAMP5&lt;/acronym&gt;. Cet enrivonnement comprend de plus l'extension PDO Mysql, très utile dans le cadre de l'utilisation du Zend Framework :-) Seulement voilà, Edgy propose un paquet php5 plus à jour que celui de &lt;a href=&quot;http://www.dotdeb.org/&quot;&gt;dotdeb&lt;/a&gt;, ce qui empêche l'installation du paquet php5-pdo-mysql de dotdeb. Ayant mieux à faire qu'installer pdo_mysql via pear, j'ai décidé d'apprendre à me servir un peu d'&lt;acronym&gt;APT&lt;/acronym&gt;, et je me propose de vous faire part de mes conclusions. Commençons par le commencement, le message d'erreur:&lt;/p&gt;


&lt;pre&gt;Les paquets suivants contiennent des dépendances non satisfaites :
  php5-pdo-mysql: Dépend: phpapi-20041225
                  Dépend: php5-common (= 5.1.6-0.dotdeb.2) mais 5.1.6-1ubuntu1 devra être installé
E: Paquets défectueux&lt;/pre&gt;


&lt;p&gt;Il suffit donc de spécifier à &lt;acronym&gt;APT&lt;/acronym&gt; que nous souhaitons utiliser la version &lt;code&gt;5.1.6-0.dotdeb.2&lt;/code&gt; du paquet &lt;code&gt;php5-common&lt;/code&gt;. Rien de plus simple ! Cela se passe dans &lt;code&gt;/etc/apt/preferences&lt;/code&gt;:&lt;/p&gt;


&lt;pre&gt;Package: php5-common
Pin: version 5.1.6-0.dotdeb.2
Pin-Priority: 1001&lt;/pre&gt;


&lt;p&gt;Et comme &lt;code&gt;libapache2-mod-php5&lt;/code&gt; dépend également de &lt;code&gt;php5-common&lt;/code&gt;, il va nous falloir faire de même:&lt;/p&gt;


&lt;pre&gt;Package: libapache2-mod-php5
Pin: version 5.1.6-0.dotdeb.2
Pin-Priority: 1001&lt;/pre&gt;


&lt;p&gt;Voilà, désormais &lt;acronym&gt;APT&lt;/acronym&gt; n'installera que la version &lt;code&gt;5.1.6-0.dotdeb.2&lt;/code&gt; de ces deux paquets, quoiqu'il arrive. Un simple &lt;code&gt;apt-get install php5-pdo-mysql&lt;/code&gt; suffit désormais pour que tout rentre dans l'ordre !&lt;/p&gt;


&lt;p&gt;A noter: &lt;a href=&quot;http://www.debian.org/doc/manuals/apt-howto/ch-apt-get.fr.html#s-pin&quot;&gt;le tutoriel qui m'a tout appris&lt;/a&gt;.&lt;/p&gt;</description>
    
    
    
          <comments>http://mirmodynamics.com/post/2006/10/01/Edgy-Eft-Dotdeb-php5-pdo-mysql-et-moi#comment-form</comments>
      <wfw:comment>http://mirmodynamics.com/post/2006/10/01/Edgy-Eft-Dotdeb-php5-pdo-mysql-et-moi#comment-form</wfw:comment>
      <wfw:commentRss>http://mirmodynamics.com/feed/atom/comments/637</wfw:commentRss>
      </item>
    
</channel>
</rss>