Magento – How to Redirect a Specific CMS Page (Contact Form) to https

cmscontact-ushttpssecure

I have a contact form, which I'm showing from CMS page. Like described at method:
http://inchoo.net/ecommerce/magento/contact-form-in-magento/

CMS page url is: customer-service-contact. I also redefined standard Mage_Contacts module. Now I need when somebody opens:

http://{website}/customer-service-contact/

he should be redirected to:

https://{website}/customer-service-contact/

I know about trick at xml:

<frontend>
    <secure_url>
        <contacts>/contacts/</contacts>
    </secure_url>
</frontend>

But if I change it to url customer-service-contact, it's not working.

How to implements this?

Best Answer

The https redirection does not work for cms pages because the Router that matches the cms pages (Mage_Cms_Controller_Router) does not check if some page should be secure.
Here is a little workaround to achieve this. It involves changing the router for the cms pages.
You will have to create a module. Let's call it Easylife_Secure:
For this you will need the following files:
app/etc/modules/Easylife_Secure.xml - the declaration file

<?xml version="1.0"?>
<config>
    <modules>
        <Easylife_Secure>
            <active>true</active>
            <codePool>local</codePool>
            <depends>
                <Mage_Core />
                <Mage_Cms /><!-- should depend on Mage_Cms -->
            </depends>
        </Easylife_Secure>
    </modules>
</config>

app/code/local/Easylife/Secure/Controller/Router.php - your new router

<?php
class Easylife_Secure_Controller_Router extends Mage_Cms_Controller_Router
{
    public function match(Zend_Controller_Request_Http $request)
    {
        if (!Mage::isInstalled()) {
            Mage::app()->getFrontController()->getResponse()
                ->setRedirect(Mage::getUrl('install'))
                ->sendResponse();
            exit;
        }

        $identifier = trim($request->getPathInfo(), '/');

        $condition = new Varien_Object(array(
            'identifier' => $identifier,
            'continue'   => true
        ));
        Mage::dispatchEvent('cms_controller_router_match_before', array(
            'router'    => $this,
            'condition' => $condition
        ));
        $identifier = $condition->getIdentifier();

        if ($condition->getRedirectUrl()) {
            Mage::app()->getFrontController()->getResponse()
                ->setRedirect($condition->getRedirectUrl())
                ->sendResponse();
            $request->setDispatched(true);
            return true;
        }

        if (!$condition->getContinue()) {
            return false;
        }

        $page   = Mage::getModel('cms/page');
        $pageId = $page->checkIdentifier($identifier, Mage::app()->getStore()->getId());
        if (!$pageId) {
            return false;
        }
        //this line checks if the page should be secure
        $this->_checkShouldBeSecure($request, '/'.$identifier);
        $request->setModuleName('cms')
            ->setControllerName('page')
            ->setActionName('view')
            ->setParam('page_id', $pageId);
        $request->setAlias(
            Mage_Core_Model_Url_Rewrite::REWRITE_REQUEST_PATH_ALIAS,
            $identifier
        );

        return true;
    }
    protected function _checkShouldBeSecure($request, $path = '')
    {

        if (!Mage::isInstalled() || $request->getPost()) {
            return;
        }

        if ($this->_shouldBeSecure($path) && !$request->isSecure()) {
            $url = $this->_getCurrentSecureUrl($request);
            if ($request->getRouteName() != 'adminhtml' && Mage::app()->getUseSessionInUrl()) {
                $url = Mage::getSingleton('core/url')->getRedirectUrl($url);
            }

            Mage::app()->getFrontController()->getResponse()
                ->setRedirect($url)
                ->sendResponse();
            exit;
        }
    }
    protected function _shouldBeSecure($path)
    {
        return substr(Mage::getStoreConfig('web/unsecure/base_url'), 0, 5) === 'https'
            || Mage::getStoreConfigFlag('web/secure/use_in_frontend')
                && substr(Mage::getStoreConfig('web/secure/base_url'), 0, 5) == 'https'
                && Mage::getConfig()->shouldUrlBeSecure($path);
    }
    protected function _getCurrentSecureUrl($request)
    {
        if ($alias = $request->getAlias(Mage_Core_Model_Url_Rewrite::REWRITE_REQUEST_PATH_ALIAS)) {
            return Mage::getBaseUrl('link', true).ltrim($alias, '/');
        }

        return Mage::getBaseUrl('link', true).ltrim($request->getPathInfo(), '/');
    }
}

The method match is the same as the one in the cms router, it just has one line that checks if the path should be secure. The rest of the methods are copied from the standard router. app/code/local/Easylife/Secure/etc/config.xml - the configuration file

<?xml version="1.0"?>
<config>
    <modules>
        <Easylife_Secure>
            <version>0.0.1</version>
        </Easylife_Secure>
    </modules>
    <global>
        <events>
            <controller_front_init_routers>
                <observers>
                    <cms><!-- change the cms router -->
                        <class>Easylife_Secure_Controller_Router</class>
                        <method>initControllerRouters</method>
                    </cms>
                </observers>
            </controller_front_init_routers>
        </events>
    </global>
    <frontend>
        <secure_url><!-- list here your secure pages. one slash (/) and the page identifier -->
            <customer_service_contact>/customer-service-contact</customer_service_contact>
        </secure_url>
    </frontend>
</config>

Clear the cache and you are done.
[EDIT]
This small extension works for the general case, for all cms pages, I added it here for 'posterity', but I agree with Alex on this. For your specific case, you should use the standard contacts page and customize its template or with additional blocks