Page 1 of 2

Looking for Simple, Elegant way to keep HTTPS and HTTP urls straight

Posted: Mon Aug 03, 2009 10:15 pm
by kendo451
I've read the posts on the forums that I can find pertaining to forcing https or http on pages in CMSMS.  Short of making an entire site SSL with mod_rewrite, what is the most elegant way to make a page https, and make the links in the menu and selflink correct?

My solution, which is somewhat tedious, is:

1. Put ssl in Extra1 of all the pages that need SSL.

2. Copy the plugin function.cms_selflink.php and make a new one called function.cms_selflink_ssl.php which has the following modification starting around line 78:

Code: Select all

		# check if the page exists in the db
		$manager =& $gCms->GetHierarchyManager();
		$node =& $manager->sureGetNodeByAlias($page);
		if (!isset($node)) return;
		$content =& $node->GetContent();
		if ($content !== FALSE)
		{
			$pageid = $content->Id();
			$alias = $content->Alias();
			$name = $content->Name(); //mbv - 21-06-2005
			$url = $content->GetUrl();
			$menu_text = $content->MenuText();
			$titleattr = $content->TitleAttribute();
			$ssl = $content->extra1();  // This line added by KENDO451
		}
		
		/* Mod by KENDO451 */
		
/* Mod by KGriffith */
		
		$parts = explode( ':' , $url );
		if ( ''!=$ssl )
		{
			$parts[0] = 'https';
		}
		else 
		{
			$parts[0] = 'http';
		}
		$url = '';
		foreach ($parts as $part)
		{
			$url.= $part;
		}
Also have to find and replace "cms_selflink(" with "cms_selflink_ssl(" in this plugin.

3. Modify my menu calls to include the parameter loadprops=1

4. Add the following block of code to my menu templates right after {foreach from=$nodelist item=node}

Code: Select all

{* If extra 1 is set make the url https, else make it http *}
{if isset($node->extra1)}
{https url=$node->url assign='nodeurl'}
{else}
{http url=$node->url assign='nodeurl'}
{/if}
Then replace {$node=>url} calls in the menu template to {$nodeurl}

5. Create user defined tags {https} and {http} that change the url to fit the requirement for the menu.

6. Create a plugin function to check the URL and re-direct if it is not set to http or https.

Code: Select all

<?php

# {checkpageurl} should be in <head> of template to generate canonical tag
#
# use {checkpageurl redirect=true} for 301 redirect
#

function smarty_cms_function_checkpageurl($params, &$smarty)
{

    global $gCms;
    $redirect = false;
    $stripExt = '';
    $ignoreModSubPage = false;

    $config = &$gCms->config;
    if(isset($config["page_extension"]) && !empty($config["page_extension"])) {
        $stripExt = $config["page_extension"];
        }

    $manager = &$gCms->GetHierarchyManager();

    $thispage = $gCms->variables['content_id'];
	
	$cgsimple = $smarty->get_template_vars('cgsimple');
    $ssl = $cgsimple->get_page_content($thispage, 'extra1');

    $trail = "";

    #Check if user has specified a redirect to proper url, otherwise use default
    if (isset($params['redirect'])) {
        $redirect = $params['redirect'];
    }   else {
        $redirect = false;
    }

    $endNode = &$manager->sureGetNodeById($thispage);

    if (isset($endNode))
    {
        $content =& $endNode->getContent();
        $contentURL = $content->getURL();

		// Content url defaults to http.  If extra 1 has been set, change $contentURL to https
		// Do this by taking the url apart and putting it back together		
		if ("" != $ssl && "" != $contentURL) {
			$urlparts = explode(":", $contentURL);
			$contentURL = "https:";
			foreach($urlparts as $key => $part) {
				if ($key != 0) {
					$contentURL .= $part;
				}
			}
		}
		
        $currentURL = curPageURL();
		
         if ($contentURL != "") {
            if($redirect && $contentURL != $currentURL && strpos($currentURL,$contentURL)===false) {
                # 3rd check strpos - prevents redirect if parameters on url

                // There is one last check we should do... let's strip the config-mandated extension
                // from the URL and see if the current page is a sub-page that's module-generated (ex: glossary module definitions)
                if(!empty($stripExt)) {
                    $cleanedURL = str_replace($stripExt, '', $contentURL).'/';

                    if(!empty($cleanedURL) && $cleanedURL != $currentURL && strpos($currentURL, $cleanedURL) !== false) {
                        // this page is likely a module generated page
                        $ignoreModSubPage = true;
                    }
                }		
				
                if(!$ignoreModSubPage) {
                    # output header redirect
                    header('Location: '.$contentURL,TRUE,301);
                }
				
				// Check to see if current URL is https
				elseif("" != $ssl && strpos("https",$currentURL)===false) {
					$urlparts = explode(":",$currentURL);
					$contentURL = "https:";
					foreach($urlparts as $key => $part) {
						if (0!=$key) {
						$contentURL .= $part;
						}				
					}
    			# output header redirect
    			header('Location: '.$contentURL,TRUE,301);
				}				
				
            }

            if(!$ignoreModSubPage) {
                $trail = '<link rel="canonical" href="'.$contentURL.'" />';
            }
         }
    }
	
	
	
    return $trail;
}

function smarty_cms_help_function_checkpageurl() {
  echo "Func to output current page URL and redirect if not correct (needs redirect=true parameter)";
}

function smarty_cms_about_function_checkpageurl() {
  echo "Func to output current page URL and redirect if not correct (needs redirect=true parameter)";
}

function curPageURL() {
 $pageURL = 'http';
 if ($_SERVER["HTTPS"] == "on") {$pageURL .= "s";}
 $pageURL .= "://";
 if ($_SERVER["SERVER_PORT"] != "80") {
  $pageURL .= $_SERVER["SERVER_NAME"].":".$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"];
 } else {
  $pageURL .= $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];
 }
 return $pageURL;
}

?>
So that is a lot of work.  Other than combining the {https} and {http} UDT's into one with a parameter to indicate which action, is there a simpler way to do this?

Thanks,

Ken

Re: Looking for Simple, Elegant way to keep HTTPS and not HTTPS urls straight

Posted: Mon Aug 03, 2009 11:29 pm
by kendo451
I can't even get all these parts to work together. :-(

I'm just going to force ssl on the whole site with mod_rewrite...

Re: Looking for Simple, Elegant way to keep HTTPS and HTTP urls straight

Posted: Wed Aug 05, 2009 8:04 pm
by nhaack
The idea is actually pretty sweet. Ideally, you just have a check box to tick in the options-tab of a page. I think with content types and your initial work, it should be possible to have something like that. That would be a nice feature request.

Thanks for sharing the idea
Best
Nils

Re: Looking for Simple, Elegant way to keep HTTPS and HTTP urls straight

Posted: Wed Aug 05, 2009 11:44 pm
by calguy1000
I may look at doing a simple checkbox or something in 1.7 to do https://mysite.com/path/to/page-alias instead of http://mysite.com/path/to/page-alias on a page by page basis.

I could've used it a couple of times.

BTW: (and you didn't hear this from me).  If you're in to some modifications that make your site un-supportable... I'd look at lib/classes/class.content.inc.php in the GetURL method... I think (though I may be wrong) that that is the only place you'd really only have to make changes to support https on selected pages.

Re: Looking for Simple, Elegant way to keep HTTPS and HTTP urls straight

Posted: Thu Aug 06, 2009 6:53 am
by vilkis
Hi,
thanks for ideas. I need this feature at the moment.
vilkis

Re: Looking for Simple, Elegant way to keep HTTPS and HTTP urls straight

Posted: Thu Aug 27, 2009 7:01 am
by essexboyracer
Hi guys,

is this fixed? I had a look inconfig.php and on line 74 it replaces http with https. or is that a global thing, i.e. your whole site is running under https?

Expanding on calguys unsupportable idea, would the change in class.content.inc.php on line 1513 be something like adding

Code: Select all


			// How would I set this in the function GETUrl?
			$ssl = $content->extra1();

			if ($config['use_hierarchy'] == true && $ssl)
			{
				$config['root_url'] = str_replace('http','https',$config['root_url']);
				$url = $config['root_url']. '/' . $this->HierarchyPath() . (isset($config['page_extension'])?$config['page_extension']:'.html');
			}
I wouldnt know how to get whether a page is to be run under ssl into the function. Unless in config.php I can list page HierarchyPath's that need to be ssl, and check for them in the above

Re: Looking for Simple, Elegant way to keep HTTPS and HTTP urls straight

Posted: Thu Aug 27, 2009 12:12 pm
by kendo451
The line in config that replaces http with https is based on whether the server is in https mode.

So, if you use the solution I was working on (which needs to be perfected before it works), you would have the page detect whether it should be https or http when it starts to load.  If it is wrong, then it uses a header to force reload it in the right mode.

The config line will make sure that on a secure page ALL of your links and images are HTTPS.  And on a http page, ALL of your links and images will be http.

Re: Looking for Simple, Elegant way to keep HTTPS and HTTP urls straight

Posted: Thu Aug 27, 2009 2:55 pm
by tyman00
FYI, Page selectable SSL has been implemented into 1.7.

Re: Looking for Simple, Elegant way to keep HTTPS and HTTP urls straight

Posted: Thu Aug 27, 2009 4:00 pm
by kendo451
Super sweet!!!

Re: Looking for Simple, Elegant way to keep HTTPS and HTTP urls straight

Posted: Thu Aug 27, 2009 4:23 pm
by tyman00

Re: Looking for Simple, Elegant way to keep HTTPS and HTTP urls straight

Posted: Thu Aug 27, 2009 5:22 pm
by essexboyracer
Fantastic! Also good to see the inclusion of sqlite, so many of the projects I do are small sites which dont really warrant mysql.

Is there a release schedule to 1.7? Or is it 'as and when'?

Re: Looking for Simple, Elegant way to keep HTTPS and HTTP urls straight

Posted: Thu Aug 27, 2009 5:25 pm
by tyman00
None at the moment. There are quite a few overhauls going on, so it could be months till we even see a beta.

Re: Looking for Simple, Elegant way to keep HTTPS and HTTP urls straight

Posted: Fri Aug 28, 2009 7:06 am
by essexboyracer
So in the mean time, will this work (it does, i.e. change the URL to https, but I havnt got an SSL server to try for real) - fully inspired by what is in the svn for 1.7 class.content.inc.php, from line 1498 and will only work if you never use the Extra Page Attribute 1 for anything (apart from adding ssl into it, or something)

Code: Select all

removed
Edit: Please don't post hacks and patches to the core.  somebody with no experience will try to implement it, badly, then ask for support.  At least with a UDT, etc. it's clearly and obviously an addon

Re: Looking for Simple, Elegant way to keep HTTPS and HTTP urls straight

Posted: Sat Aug 29, 2009 12:09 am
by essexboyracer
Apologies

Re: Looking for Simple, Elegant way to keep HTTPS and HTTP urls straight

Posted: Mon Sep 07, 2009 2:32 pm
by irish
Here is what I do:

I create two UDT

NonSSL

Code: Select all

if ($_SERVER['SERVER_PORT']==443)
{
$url = "http://". $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
header("Location: $url");
}
ssl

Code: Select all

if ($_SERVER['SERVER_PORT']!=443)
{
$url = "https://". $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
header("Location: $url");
}
Then create two templates. Both are identical except one will have the {NonSSL} where the other will have {ssl} Then I assign the appropriate template to the pages as needed.

I'm sure there is an faster, more efficient way, but this one works well for me.

Can't wait for 1.7 if it has a simple checkbox for this.