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

Talk about writing modules and plugins for CMS Made Simple, or about specific core functionality. This board is for PHP programmers that are contributing to CMSMS not for site developers
kendo451

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

Post 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
Last edited by kendo451 on Tue Aug 04, 2009 12:11 am, edited 1 time in total.
kendo451

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

Post 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...
nhaack

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

Post 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
calguy1000
Support Guru
Support Guru
Posts: 8169
Joined: Tue Oct 19, 2004 6:44 pm
Location: Fernie British Columbia, Canada

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

Post 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.
Follow me on twitter
Please post system information from "Extensions >> System Information" (there is a bbcode option) on all posts asking for assistance.
--------------------
If you can't bother explaining your problem well, you shouldn't expect much in the way of assistance.
vilkis

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

Post by vilkis »

Hi,
thanks for ideas. I need this feature at the moment.
vilkis
essexboyracer
Forum Members
Forum Members
Posts: 85
Joined: Wed Jun 20, 2007 5:40 pm

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

Post 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
kendo451

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

Post 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.
tyman00
Power Poster
Power Poster
Posts: 906
Joined: Tue Oct 24, 2006 5:59 pm

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

Post by tyman00 »

FYI, Page selectable SSL has been implemented into 1.7.
If all else fails, use a bigger hammer.
M@rtijn wrote: This is a community. This means that we work together and have the same goal (a beautiful CMS), not that we try to put people down and make their (voluntary) job as difficult as can be.
kendo451

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

Post by kendo451 »

Super sweet!!!
tyman00
Power Poster
Power Poster
Posts: 906
Joined: Tue Oct 24, 2006 5:59 pm

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

Post by tyman00 »

If all else fails, use a bigger hammer.
M@rtijn wrote: This is a community. This means that we work together and have the same goal (a beautiful CMS), not that we try to put people down and make their (voluntary) job as difficult as can be.
essexboyracer
Forum Members
Forum Members
Posts: 85
Joined: Wed Jun 20, 2007 5:40 pm

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

Post 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'?
tyman00
Power Poster
Power Poster
Posts: 906
Joined: Tue Oct 24, 2006 5:59 pm

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

Post 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.
If all else fails, use a bigger hammer.
M@rtijn wrote: This is a community. This means that we work together and have the same goal (a beautiful CMS), not that we try to put people down and make their (voluntary) job as difficult as can be.
essexboyracer
Forum Members
Forum Members
Posts: 85
Joined: Wed Jun 20, 2007 5:40 pm

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

Post 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
Last edited by calguy1000 on Fri Aug 28, 2009 1:03 pm, edited 1 time in total.
essexboyracer
Forum Members
Forum Members
Posts: 85
Joined: Wed Jun 20, 2007 5:40 pm

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

Post by essexboyracer »

Apologies
irish
Forum Members
Forum Members
Posts: 101
Joined: Tue Jun 03, 2008 2:31 pm

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

Post 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.
Post Reply

Return to “Developers Discussion”