Hello Ant,

Thanks for your comment. I'd have to write a plugin that is called
from every action, or rather I'd have to automatically call the code
by injecting a caller into the symfony request bootstrapping chain.
Which works fine, I've done that in the past for example for allowing
users to switch between languages. But then I'd have to do a stat() or
md5() on the .htaccess file on every request, or even worse, I'd
actually have to read in the whole .htaccess file on every request to
check if it had changed. Reading in a whole file on every request for
something that only changes every few months isn't very efficient. Or
I'd have to keep my own flag on whether or not the app settings file
had changed, which seems brittle. On top of that, it's conceptually
not what I want to do: I don't want to check on every request, I want
to do it only when the settings changed.

Anyway, turns out that the cache:clear event will work for me because
in the production environment it needs to be called after changing the
app.yml file anyway. It's not 100% correct because in the debug
environment the settings from app.yml are updated 'silently' but it's
good enough for what I need to do at this moment. I'd still like to
ask for a 'a setting has changed' event to be added. One event for
project-, app- and module settings should be enough as the user can
then check for himself if it concerns a setting he's interested in.


Secondly, I'd like to make a comment on the wording in the
documentation, specifically the 'extending Symfony' part. The event
system is described in these terms:

"Some of the symfony classes "notify an event" at various moments of
their life."

This is if not wrong then at least misleading and not congruent with
the terminology that is used with event systems (signals,
delegates, ...) in other programming languages. It's not the events
that are notified, it's the functions or methods that are registered
as the recipients of the notification that are notified. The IMO
correct way of phrasing it is

"Some of the symfony classes "emit an event" at various moments of
their life."

'Events' are 'emitted' or 'send', and that way they 'notify' the
'recipients' or 'slots' (personally I like the naming that is used in
libsigc or boost.signals best: a 'signal' 'emits' and in that way
calls a 'slot', but I'll admit that 'signal' and 'slot' are not very
intuitive names for non native speakers. At least I know that it took /
me/ some time to accept the term 'slot')

Anyway, in my opinion, if the documentation would be changed to
replace 'notify an event' by 'send an event' or 'emit an event', that
would be a lot clearer.


Then finally, now that I'm typing this anyway ;), I might as well
describe what I did to get this to work in case anyone ever finds this
in the mailing list archives. I don't think it's common enough to
write a wiki entry about, but I thought it was halfway clever so maybe
it'll help someone in the future.

First, I have a file called .htaccess.tpl in my symfony data directory
that looks like this (only the relevant parts with some context - the
actual name of the product is replaced with 'MyProductName'):

<IfModule mod_rewrite.c>
  RewriteEngine On

  # Redirect all requests to 'downloads/MyProductName*'
  # to the latest version.
  RewriteCond %{REQUEST_URI} !^##LASTEST_VERSION_PLACEHOLDER##
  RewriteCond %{REQUEST_URI} ^/downloads/MyProductName.*
  RewriteRule ^(.*)$ ##LASTEST_VERSION_PLACEHOLDER## [R=permanent,L]

  # uncomment the following line, if you are having trouble
  # getting no_script_name to work
  #RewriteBase /

Then, this is what frontendConfiguration.class.php looks like:

<?php

function rebuild_htaccess()
{
    $template_path = sfConfig::get('sf_data_dir') . '\.htaccess.tpl';
    $output_path = sfConfig::get('sf_web_dir') . '\.htaccess';

    $input_h = fopen($template_path, 'r');
    $output_h = fopen($output_path, 'wb+');

    while ($line = fgets($input_h)) {
        $line = str_replace('##LASTEST_VERSION_PLACEHOLDER##',
sfConfig::get('app_latest_version'), $line);
        fputs($output_h, $line);
    }

    return true;
}

class frontendConfiguration extends sfApplicationConfiguration
{
    public function configure()
    {
        $this->dispatcher->connect('task.cache.clear',
'rebuild_htaccess');
    }
}

Then finally, the frontend's app.yml contains this:

all:
  latest_version:   /downloads/MyProductName_1.1.0_setup.exe


So now all I have to do when I release a new version of my product, I
change the app.yml, call cache:clear and the .htaccess is updated (the
setting is used in other places in the frontend well, of course). This
technique can be used for other ways of automatically generating other
parts of .htaccess too.

Ideally I'd move the rebuild_htaccess() function to another location
and include() it from frontEndConfiguration.class.php but that's a
details that is left as an exercise for the reader :)


cheers,

roel


On Mar 6, 2:50 am, Ant Cunningham <[email protected]>
wrote:
> Is there a specific reason youre doing it this way as opposed to just
> redirecting from the action?
>
> Roel Vanhout wrote:
> > Hi,
>
> > I want to put a certain url that is defined in the frontend's app.yml
> > and put it in my .htaccess file., in a RewriteRule (I want to redirect
> > all file downloads that match a certain pattern to the setting from
> > the app.yml - all people who link to an old version of my software
> > installer should be 301 redirected to the latest version).
>
> > So I made a .htaccess.tpl with a placeholder in the the download
> > location - '##LASTEST_VERSION##' so that I can search and replace in
> > that file and write the result to the .htaccess file. Result: except
> > for the very first request after the change to the app.yml is made,
> > the .htaccess will be up to date.
>
> > Except for one thing: I can't find a way to be notified of when the
> > app.yml is changed. I could of course regenerate the .htaccess on
> > every request but that seems like a waste and a race condition waiting
> > to happen.
>
> > So, my question: is there a way to be notified that app.yml has been
> > changed? Is there a class I can subclass? Thanks.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"symfony users" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/symfony-users?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to