Bulk Updating Magento Product Prices
Published:
Heads up! This content is more than six months old. Take some time to verify everything still works as expected.
I came up against a situation I imagine is not very unique, but is very frustrating for a client today. Thanks to updates in Google's algorithms we're adding an extra header Vary to all of our sites that run multiple themes based on user agent detection. It my case, it is the theme switching, but if you vary even for little things, it's not a bad idea to declare that variance. You not even be varying by User-Agent. But, if you hit the Drupal 7 caching layer, you're going to have a bad time.
Everything looked like it worked on my local, which of course runs
in a development mode with caching off. So when I turned on caching
to check, the real fun started. It seems I was able to declare the
extra variant header at the theme layer, but it just would not output
once cached. Investigation into the actual cache_page table showed
that the Vary: User-Agent
header was associated!
So what gives? The issue was actually in the bootstrap.inc
file and
drupal_serve_page_from_cache
function, in the way cached pages are
served. I'll snippet the relevant portions:
// Allow HTTP proxies to cache pages for anonymous users without a session // cookie. The Vary header is used to indicates the set of request-header // fields that fully determines whether a cache is permitted to use the // response to reply to a subsequent request for a given URL without // revalidation. If a Vary header has been set in hook_boot(), it is assumed // that the module knows how to cache the page. if (!isset($hook_boot_headers['vary']) && !variable_get('omit_vary_cookie')) { header('Vary: Cookie'); } if ($page_compression) { header('Vary: Accept-Encoding', FALSE); ...
So, if you do not specifically state a vary in your hook_boot
, or
start specifically omitting the cookie variance, it doesn't matter
what vary header you cache, it's going to smash it, and start over.
There are only a few solutions to this problem:
- Create a local version of
bootstrap.inc
using the settings file to point to the updated version <br />This is one step above modifying core, but promises headaches down the road. No. - Set the variable to omit cookie variance control. <br />Loss of control? No.
- Use a custom module, loaded at boot level, to declare a vary header. <br />This is the least evil of the solutions. Go with it
In custom.module, create the follow hook:
/** * - Implemenation of hook_boot */ function custom_boot(){ // Because we're swapping content based on user agent // we have to tell the cache layer we've modified // the vary header manually // see: bootstrap.inc:drupal_serve_page_from_cache() drupal_add_http_header('vary', 'Cookie,User-Agent'); }
You'll also need to register your module as a boot module. This can
be done at install using this hook in the custom.install
file:
function custom_install(){ db_query("UPDATE {system} SET bootstrap = 1 WHERE name = 'custom'"); }
But, if it's already running? Clear cache, and run the same command against the database.