So, if you're seeing issues with double encoding (%252d where it should only encode a %2d for a '-' etc) this was my resolution.
/lib/general.php
Code: Select all
/**
* Convert an already search engine friendly based string back to the normal text equivalent.
* (this is the incoming route)
*
* @param string The search engine friendly version of the string.
* @return string The normal textual version of the string.
*/
function MakeURLNormal($val)
{
if (strpos($val,'_')!==false){
//$val = str_replace("%2d", " ", $val);
}
else {$val = str_replace("-", " ", $val);}
//$val = str_replace("-", " ", $val);
//$val = str_replace("–", "-", $val);
$val = str_replace("%25a3", "%A3", $val);
$val = str_replace("_", " ", $val);
$val = urldecode($val);
$val = str_replace("%2f", "/", $val);
$val = str_replace("%2d", "-", $val);
$val = str_replace("%2b", "+", $val);
return $val;
}
/**
* Convert a text string in to a search engine friendly based URL.
* (this my adapted SEO Friendly implementation)
*
* @param string The text string to convert.
* @return string The search engine friendly equivalent.
*/
function MakeURLSafeNEW($val)
{
$val = str_replace(" ", "_", $val);
$val = str_replace("/", "{47}", $val);
$val = urlencode($val);
$val = str_replace("£", "%A3", $val);
$val = str_replace("-", "%2d", $val);
$val = str_replace("+", "-", $val);
return $val;
}
/**
* Convert a text string in to a search engine friendly based URL.
* (this is the original implementation)
*
* @param string The text string to convert.
* @return string The search engine friendly equivalent.
*/
function MakeURLSafe($val)
{
$val = str_replace("-", "%2d", $val);
$val = str_replace("+", "%2b", $val);
$val = str_replace("+", "%2b", $val);
$val = str_replace("/", "%2f", $val);
$val = urlencode($val);
$val = str_replace("+", "-", $val);
return $val;
}
Ok, so now we have an additional route for the SEO friendlies to be generated and parsed no incoming, time to add them in!
They get attached (same file) here:
Code: Select all
/**
* Generate the link to a product.
*
* @param string The name of the product to generate the link to.
* @return string The generated link to the product.
*/
function ProdLink($prod)
{
if ($GLOBALS['EnableSEOUrls'] == 1) {
return sprintf("%s/%s/%s.html", GetConfig('ShopPathNormal'), PRODUCT_LINK_PART, MakeURLSafeNEW($prod));
} else {
return sprintf("%s/products.php?product=%s", GetConfig('ShopPathNormal'), MakeURLSafe($prod));
}
}
Code: Select all
/**
* Generate the link to a brand name.
*
* @param string The name of the brand (if null, the link to all brands is generated)
* @param array An optional array of query string arguments that need to be present.
* @param boolean Set to false to not separate query string arguments with & but use & instead. Useful if generating a link to use for a redirect.
* @return string The generated link to the brand.
*/
function BrandLink($brand=null, $queryString=array(), $entityAmpersands=true)
{
// If we don't have a brand then we're just generating the link to the "all brands" page
if($brand === null) {
if ($GLOBALS['EnableSEOUrls'] == 1) {
$link = sprintf("%s/%s/", $GLOBALS['ShopPathNormal'], BRAND_LINK_PART, MakeURLSafeNEW($brand));
} else {
$link = sprintf("%s/brands.php", $GLOBALS['ShopPathNormal'], MakeURLSafe($brand));
}
}
else {
if ($GLOBALS['EnableSEOUrls'] == 1) {
$link = sprintf("%s/%s/%s.html", $GLOBALS['ShopPathNormal'], BRAND_LINK_PART, MakeURLSafeNEW($brand));
} else {
$link = sprintf("%s/brands.php?brand=%s", $GLOBALS['ShopPathNormal'], MakeURLSafe($brand));
}
}
if($entityAmpersands) {
$ampersand = '&';
}
else {
$ampersand = '&';
}
if(is_array($queryString) && !empty($queryString)) {
if ($GLOBALS['EnableSEOUrls'] == 1) {
$link .= '?';
}
else {
$link .= $ampersand;
}
$qString = array();
foreach($queryString as $k => $v) {
$qString[] = $k.'='.urlencode($v);
}
$link .= implode($ampersand, $qString);
}
return $link;
}
Code: Select all
/**
* Generate the link to a category.
*
* @param int The ID of the category to generate the link to.
* @param string The name of the category to generate the link to.
* @param boolean Set to true to base this link as a root category link.
* @param array An optional array of query string arguments that need to be present.
* @return string The generated link to the category.
*/
function CatLink($CategoryId, $CategoryName, $parent=false, $queryString=array())
{
// Workout the category link, starting from the bottom and working up
$link = "";
$arrCats = array();
if ($parent === true) {
$parent = 0;
$arrCats[] = $CategoryName;
} else {
static $categoryCache;
if(!is_array($categoryCache)) {
$categoryCache = array();
$query = "SELECT catname, catparentid, categoryid FROM [|PREFIX|]categories order by catsort desc, catname asc";
$result = $GLOBALS['ISC_CLASS_DB']->Query($query);
while ($row = $GLOBALS['ISC_CLASS_DB']->Fetch($result)) {
$categoryCache[$row['categoryid']] = $row;
}
}
if(empty($categoryCache)) {
return '';
}
if (isset($categoryCache[$CategoryId])) {
$parent = $categoryCache[$CategoryId]['catparentid'];
if ($parent == 0) {
$arrCats[] = $categoryCache[$CategoryId]['catname'];
} else {
// Add the first category
$arrCats[] = $CategoryName;
$lastParent=0;
while ($parent != 0 && $parent != $lastParent) {
$arrCats[] = $categoryCache[$parent]['catname'];
$lastParent = $categoryCache[$parent]['categoryid'];
$parent = (int)$categoryCache[$parent]['catparentid'];
}
}
}
}
$arrCats = array_reverse($arrCats);
if ($GLOBALS['EnableSEOUrls'] == 1) {
for ($i = 0; $i < count($arrCats); $i++) {
$link .= sprintf("%s/", MakeURLSafeNEW($arrCats[$i]));
}
} else {
for ($i = 0; $i < count($arrCats); $i++) {
$link .= sprintf("%s/", MakeURLSafe($arrCats[$i]));
}
}
// Now we reverse the array and concatenate the categories to form the link
if ($GLOBALS['EnableSEOUrls'] == 1) {
$link = sprintf("%s/%s/%s", $GLOBALS['ShopPathNormal'], CAT_LINK_PART, $link);
} else {
$link = trim($link, "/");
$link = sprintf("%s/categories.php?category=%s", $GLOBALS['ShopPathNormal'], $link);
}
if(is_array($queryString) && !empty($queryString)) {
if ($GLOBALS['EnableSEOUrls'] == 1) {
$link .= '?';
}
else {
$link .= '&';
}
$link .= http_build_query($queryString);
}
return $link;
}
This solved a major headache for us, we've still a LOT of 301 work to do to catch reference to any of the old links floating around on the net and on people's bookmark list, but when that is done and dusted we should be completely SEO URL friendly!