Magento - How to switch Base URLs without modifying the Database

As Magento keeps its base URL in database, there is no easy way of accessing the same database from two different URLs (dev/ staging) or moving the same database to staging environment from development without updating the core_config_data table.

After fiddling around with Magento core, I found that getBaseUrl() is responsible of retrieving base URL. So If we could override getBaseUrl() method to get the base URL from dev or staging environments without depending on the database, then we could keep database records with live settings.

Below code will explain how I achieved this task and the code itself is explainable.

  • app/etc/modules/My_Configurator.xml
    <?xml version="1.0"?>
    <config>
        <modules>
          <my_configurator>
            <active>true</active>
            <codePool>local</codePool>
          </my_configurator>
        </modules>
    </config>
  • app/code/local/My/Configurator/etc/config.xml
  <?xml version="1.0"?>
  <config>
    <global>
      <models>
        <core>
          <rewrite>
            <store>My_Configurator_Model_Store</store>
            </rewrite>
          </core>
        </models>
      </global>
    </config>
  • app/code/local/My/Configurator/Model/Store.php
    <?php
        class My_Configurator_Model_Store extends Mage_Core_Model_Store
        {
            public function getBaseUrl($type=self::URL_TYPE_LINK, $secure=null)
            {
                $url = parent::getBaseUrl($type, $secure);
                //domain from the DB
                $host = parse_url($url, PHP_URL_HOST);
                return str_replace('://'.$host.'/', '://'.$_SERVER['HTTP_HOST'].'/', $url);
            }
        }

Note: Make sure you disable this extension from production server as we want to run getBaseUrl() method from the Core.

Happy Coding..

###Comments

jennychalek

This is making me pull my hair out. I used this exact code and even though my IDE recognizes that the class has been successfully overriden, magento itself does not seem to know or care - it never calls the override class, just the original. Is there some sort of config setting I'm missing? Any other ideas what could cause this? Grasping at straws at this point.

Thilanga Pitigala

@jennychalek Did you enable the extension? Can you see it under Admin->System->Configuration->Advanced?


Symfony2 - Load different templates based on user agent

If you want to load different templates for different user agents while keeping the same backend code base, you can accomplish this simply in 2 ways.

1. Responsive Template
2. Load different templates against user agents.

In this blog post I’m trying to demonstrate the option 2 (load different templates against user agents)

The trick is to use RequestFormat in Symfony

  1. Create a Request Listener

         php app/console generate:bundle --namespace=Acme/RequestListenerBundle --format=yml
    

    Note: You don’t need Controller or Tests directories

    Past the below code to AcmeRequestListnerBundle.php

         <?php
             namespace Acme\RequestListenerBundle;
             use Symfony\Component\HttpKernel\HttpKernelInterface;
             use Symfony\Component\HttpKernel\Event\GetResponseEvent;
    
             class AcmeRequestListenerBundle
             {
                 public function onKernelRequest(GetResponseEvent $event)
                 {
                     $request = $event->getRequest();
    
                     if(preg_match('/(alcatel|amoi|android|avantgo|blackberry|benq|cell|cricket|docomo|elaine|htc|
                         iemobile|iphone|ipad|ipaq|ipod|j2me|java|midp|mini|mmp|mobi|motorola|nec-|nokia|palm|panasonic|
                         philips|phone|playbook|sagem|sharp|sie-|silk|smartphone|sony|symbian|t-mobile|telus|up\.browser|
                         up\.link|vodafone|wap|webos|wireless|xda|xoom|zte)/i', $request->headers->get('user-agent')
                             )
                         )
                     {
                         $request->setRequestFormat('mobile', 'text/html');
                     }else {
                         $request->setRequestFormat('html', 'text/html');
                     }
                 }
    
                 private function setFormat (\Symfony\Component\HttpFoundation\Request $request, $format='html')
                 {
                     $request->setRequestFormat($format, 'text/html');
                 }
             }
         ?>
    
  2. Create a test action in your controller
    • Action Method

            /**
            * @Route("/test", name="_demo_test")
            * @Template()
            */
      
            public function testAction()
            {
                return array(
                    'name' => 'Thilanga Pitigala',
                );
            }
      
    • Run and Verify the route

            php app/console router:debug | grep _demo_test
      
    • Template

      Create the template for newly created action Acme/DemoBundle/Resources/views/Demo/test.html.twig

                {% extends "AcmeDemoBundle::layout.html.twig" %}
                    {% block title "Hello " %}
                    {% block content %}
                    Hello Desktop !
                {% endblock %}
                  
      
  3. Create a Service using RequestListener Add below code to config.yml

         services: acme.listener.request:
         class: Acme\RequestListenerBundle\AcmeRequestListenerBundle
         tags: - {
                 name: kernel.event_listener,
                 event: kernel.request,
                 method: onKernelRequest
             }
    
    • Run

            php app/console container:debug | grep acme.listener.request
      

      and That will output the newly created service

  4. Test RequestListener service Try visiting the web applications from mobile device. It will throw an error complaining about missing test.mobile.twig file.

    Create the test.mobile.twig file in Acme/DemoBundle/Resources/views/Demo/test.html.twig as we created the test.html.twig template. Now you will be able to see the mobile template from mobile devices while desktop template load for desktop agents.

    By that way we can load different templates for different agents without doing any responsive templates.

Happy Coding..