Jump to content
Sign in to follow this  
enigma1

[Contribution] SEO-G

Recommended Posts

Post # 369

RE: .htaccess

<IfModule mod_setenvif.c>
<IfDefine SSL>
SetEnvIf User-Agent ".*MSIE.*" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
</IfDefine>
</IfModule>

is official osC: oscommerce-2.2ms2-060817


"If you're working on something new, then you are necessarily an amateur."

Share this post


Link to post
Share on other sites

Many thanks enigma for your fantastic contribution. I've implemented it on my shop www.mobiliparts.com and it's perfect. Howether, do you plan to support multi-languaguges URL?

 

Example :

http://www.mystore.com/french-description-...st-product.html

http://www.mystore.com/english-description...st-product.html

 

The language parameter is this one : http://www.mobiliparts.com/index.php?language=fr

 

Best Regards

 

Michel

Share this post


Link to post
Share on other sites
.htaccess:

<IfModule mod_setenvif.c>
 <IfDefine SSL>
   SetEnvIf User-Agent ".*MSIE.*" \
            nokeepalive ssl-unclean-shutdown \
            downgrade-1.0 force-response-1.0
 </IfDefine>
</IfModule>
#-MS- SEO-G Added
Options +FollowSymLinks
RewriteEngine On
# Next line must be changed to match your osCommerce folder - the relative path 
RewriteBase /
RewriteRule ^(.*).html$ root.php?$1.html&%{QUERY_STRING} [R=301,L]
#-MS- SEO-G Added EOM

 

Sorry missed that part earlier.

 

Ok this line from the code you posted

 

RewriteRule ^(.*).html$ root.php?$1.html&%{QUERY_STRING} [R=301,L]

 

where did you find it? I am seeing the rewriterule comes with different flavors from various posters. Although it's clear in the documentation

 

RewriteRule ^(.*).html$ root.php?$1.html&%{QUERY_STRING}

Edited by enigma1

Share this post


Link to post
Share on other sites
Many thanks enigma for your fantastic contribution. I've implemented it on my shop www.mobiliparts.com and it's perfect. Howether, do you plan to support multi-languaguges URL?

 

Example :

http://www.mystore.com/french-description-...st-product.html

http://www.mystore.com/english-description...st-product.html

 

The language parameter is this one : http://www.mobiliparts.com/index.php?language=fr

 

Best Regards

 

Michel

That's not multilanguage urls, having just the language parameter translated. Cause this already exists if you set the safe mode to false from your seo-g configuration. Or if you add few extra lines to translate the language parameter like it was done with the "page" parameter.

 

You want the actual links showing in different languages now isn't it? And for this the routines that create the seo-g strings need to change in order to support it. Depending on the language set, the create_safe_string and create_safe_name functions have to load different sets for translation. Probably through the dbase using a preg expression for each language via a different table.

 

I may add the basic structure at some point for multilingual support, but not the character expressions as they're different for each language. However once it's done it should be fairly easy to add the char set for filtering.

Share this post


Link to post
Share on other sites
That's not multilanguage urls, having just the language parameter translated. Cause this already exists if you set the safe mode to false from your seo-g configuration. Or if you add few extra lines to translate the language parameter like it was done with the "page" parameter.

 

You want the actual links showing in different languages now isn't it? And for this the routines that create the seo-g strings need to change in order to support it. Depending on the language set, the create_safe_string and create_safe_name functions have to load different sets for translation. Probably through the dbase using a preg expression for each language via a different table.

 

I may add the basic structure at some point for multilingual support, but not the character expressions as they're different for each language. However once it's done it should be fairly easy to add the char set for filtering.

 

You understand exactly what I mean.

 

I sugess you few changes on seo_URL.php. Here you can see my file including changes between "//Perso". This one works for french. Few improvments should be made to support all occidental languages.

Edited by Michel Racat

Share this post


Link to post
Share on other sites
You understand exactly what I mean.

 

I sugess you few changes on seo_URL.php. This one works for french. Few improvments should be made to support all occidental languages.

You need to post the code here. Download links outside the osC site can disappear, you know.

Share this post


Link to post
Share on other sites
You need to post the code here. Download links outside the osC site can disappear, you know.

Here is the code :

<?php
/*
//----------------------------------------------------------------------------
// Copyright (c) 2006-2007 Asymmetric Software - Innovation & Excellence
// Author: Mark Samios
// http://www.asymmetrics.com
// SEO-G URL class
// Processes SEO tables and urls, generates seo links
//----------------------------------------------------------------------------
// Script is intended to be used with:
// osCommerce, Open Source E-Commerce Solutions
// http://www.oscommerce.com
// Copyright (c) 2003 osCommerce
//----------------------------------------------------------------------------
// Released under the GNU General Public License
//----------------------------------------------------------------------------
*/

 class seoURL {
var $path, $query, $params_array, $error_level, $handler_flag;
function seoURL() {
  $this->path = $this->query = '';
  $this->params_array = array();
  $this->query_array = array();
  $this->error_level = 0;
}

function create_safe_string($string, $separator=SEO_DEFAULT_WORDS_SEPARATOR) {
  $string = preg_replace('/\s\s+/', ' ', trim($string));
  $string = preg_replace("/[^0-9a-z\-_\/]+/i", $separator, strtolower($string));
  $string = trim($string, $separator);
  $string = str_replace($separator . $separator . $separator, $separator, $string);
  return $string;
}

function create_safe_name($string, $separator=SEO_DEFAULT_WORDS_SEPARATOR) {
  $string = preg_replace('/\s\s+/', ' ', trim($string));
//Perso
$string = strtr($string, 'ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìí
îïðòóôõöùúûüýÿ', 'AAAAAACEEEEIIIIOOOOOUUUUYaaaaaaceeeeiiiioooooouuuuyy'); //Remove accent
  $string = preg_replace("/[^0-9a-z\-_]+/i", $separator, strtolower($string));
  $string = trim($string, $separator);
  $string = str_replace($separator . $separator . $separator, $separator, $string);
  if(SEO_DEFAULT_WORD_LENGTH > 1) {
	$words_array = explode($separator, $string);
	if( is_array($words_array) ) {
	  for($i=0, $j=count($words_array); $i<$j; $i++) {
		if(strlen($words_array[$i]) < SEO_DEFAULT_WORD_LENGTH) {
		  unset($words_array[$i]);
		}
	  }
	  if(count($words_array))
		$string = implode($separator, $words_array);
	}
  }
  return $string;
}


// Get osc url from a passed seo url
function get_osc_url($seo_url, &$url, &$url_params, &$url_parse) {
  // Validate REQUEST_URI in case we got a redirect from a server script. May needed with some servers
  $this->validate_uri($seo_url);

  $url = $url_params = $url_parse = $result = false;
  $seo_left = explode('?', $seo_url);
  if( !is_array($seo_left) ) {
	$url_parse = parse_url($seo_url);
	return $result;
  }

  $key = md5($seo_left[0]);
  $check_query = tep_db_query("select seo_url_get, seo_url_org from " . TABLE_SEO_URL . " where seo_url_key = '" . tep_db_input($key) . "'");
  if( $seo_array = tep_db_fetch_array($check_query) ) {
	$url = $seo_array['seo_url_org'];

	$url_parse = parse_url($url);
	if( !isset($url_parse['query']) ) {
	  $url_query = '';
	} else {
	  $url_query = $url_parse['query'];
	}
	$url_params = explode('&', $url_query);

	if( !is_array($url_params) ) {
	  $url_params = array();
	}

	tep_db_query("update " . TABLE_SEO_URL . " set seo_url_hits = seo_url_hits+1 where seo_url_key = '" . tep_db_input($key) . "'");
	$result = true;
  } else {
	$url_parse = parse_url($seo_url);
  }
  return $result;
}

// Convert osc url to an html url. Do not pass the session name/id to this function
function get_seo_url($url, &$separator, $store=true) {

  if( SEO_DEFAULT_ENABLE == 'false' ) {
	return $url;
  }

  if( SEO_CONTINUOUS_CHECK == 'false' ) {
	// Check if the url is recorded, if so skip processing
	$check_query = tep_db_query("select seo_url_get from " . TABLE_SEO_URL . " where seo_url_org = '" . tep_db_input(tep_db_prepare_input($url)) . "'");
	if( $seo_array = tep_db_fetch_array($check_query) ) {
	  $separator = '?';
	  return $seo_array['seo_url_get'];
	}
  }

  $seo_url = '';
  $result = $this->parse_params($url, $seo_url);

  if( !$result || $store !== true ) {
	return $url;
  }

  $key = md5($seo_url);
  $check_query = tep_db_query("select seo_url_get, seo_url_org from " . TABLE_SEO_URL . " where seo_url_key = '" . tep_db_input($key) . "'");
  if( $seo_array = tep_db_fetch_array($check_query) ) {
	if( $seo_array['seo_url_org'] != $url && SEO_CONTINUOUS_CHECK == 'true' ) {
	  tep_db_query("delete from " . TABLE_SEO_URL . " where seo_url_key = '" . tep_db_input($key) . "'");
	  $sql_data_array = array(
							  'seo_url_key' => tep_db_prepare_input($key),
							  'seo_url_get' => tep_db_prepare_input($seo_url),
							  'seo_url_org' => tep_db_prepare_input($url),
							  'date_added' => 'now()'
							 );
	  tep_db_perform(TABLE_SEO_URL, $sql_data_array);
	}
  } else {
	$sql_data_array = array(
							'seo_url_key' => tep_db_prepare_input($key),
							'seo_url_get' => tep_db_prepare_input($seo_url),
							'seo_url_org' => tep_db_prepare_input($url),
							'date_added' => 'now()'
						   );
	tep_db_perform(TABLE_SEO_URL, $sql_data_array);
  }
  $separator = '?';
  return $seo_url;
}

function parse_params(&$url, &$seo_url) {
  $result = false;
  $seo_url = '';
  $url = trim($url, '&');
  $seo_array = parse_url($url);

  // Validate result
  if( !is_array($seo_array) || !isset($seo_array['path']) ) {
	return $result;
  }
  $this->path = basename($seo_array['path']);
  // Process the query part.
  $query = isset($seo_array['query'])?$seo_array['query']:'';

  if( tep_not_null($query) ) {
	$query = htmlspecialchars(urldecode($query));
	$query = str_replace('&', '&', $query);
  }
  $this->query = $query;

  // Check exclusion list scripts and parameters
  if( $this->exclude_script() ) {
	return $result;
  }

  // Store original query
  $osc_query = $query;

  $fragment = isset($seo_array['fragment'])?$seo_array['fragment']:'';
  $osc_path = $path = $seo_array['path'];
  if( tep_not_null($query) ) {
	if( count($this->params_array) ) {
	  $other = false;
	  $result = $this->translate_params($other, $query);
	  // Check if safe mode is on and unknown parameters were detected, in which case abort.
	  if( $other && SEO_DEFAULT_SAFE_MODE == 'true') {
		return false;
	  }
	  if($result == 2) {
		$this->error_level = 2;
		return false;
	  }
	}
	$query = $this->create_safe_string($query, SEO_DEFAULT_PARTS_SEPARATOR);
  }

  if( tep_not_null($fragment) ) {
	$fragment = SEO_DEFAULT_PARTS_SEPARATOR . $fragment;
  }
  if( tep_not_null($path) ) {
	if( tep_not_null($query) || tep_not_null($fragment) ) {
	  if($result == 1) {
		$tmp_array = explode('/', $path);
		$count = is_array($tmp_array)?count($tmp_array):0;
		if( $count ) {
		  unset($tmp_array[$count-1]);
		  $path = implode('/', $tmp_array);
		} else {
		  $path = '';
		}
		$path .= '/';
	  } else {
		$path = str_replace('.php', SEO_DEFAULT_INNER_SEPARATOR, $path);
	  }
	} else {
	  $path = str_replace('.php', '', $path);
	}
  }

  if( tep_not_null($osc_query) ) {
	$this->eliminate_session();
	if( count($this->params_array) ) {
	  $osc_query = '?' . implode('&', $this->params_array);
	} else {
	  $osc_query = '';
	}
  }

  $url = $seo_array['scheme'] . '://' .  $seo_array['host'] . $osc_path . $osc_query;
  $seo_url = $seo_array['scheme'] . '://' .  $seo_array['host'] . $path . $query . $fragment . SEO_DEFAULT_EXTENSION;
  $seo_url = str_replace('___', '_', $seo_url);
  return true;
}

// Convert supported url parameters
function translate_params(&$other, &$query) {
  $this->handler_flag = $other = false;
  $result = 0;
  $flags_array = array('other' => false);
  $seo_params_array = array();
  $params_array = array();
  $array_and = $this->params_array;
  foreach ($array_and as $key => $value) {
	$inner = explode('=', $value);
	if( !is_array($inner) || count($inner) != 2) {
	  if( SEO_STRICT_VALIDATION == 'false' ) {
		$this->assign_default($params_array, $value);
	  }
	  $flags_array['other'] = true;
	  continue;
	}
	// No Sessions should ever passed to this class and this is going to be enforced.
	if( $inner[0] == tep_session_name() ) {
	  continue;
	}

	switch($inner[0]) {
	  case 'products_id':
		if( isset($flags_array['products_id']) || !tep_not_null($inner[1]) ) break;
		// Do not handle attributes. If detected signal abort. This is effective for Safe Mode only
		if(stristr($inner[1], '{') ) {
		  $flags_array['other'] = true;
		} elseif( !is_numeric($inner[1]) ) {
		  return 2;
		}

		$this->auto_builder($inner[0], $inner[1]);
		$params_query_raw = "select s2p.seo_name, st.sort_order, st.seo_types_linkage, st.seo_types_prefix, st.seo_types_handler from " . TABLE_SEO_TO_PRODUCTS . " s2p left join " . TABLE_SEO_TYPES . " st on (s2p.seo_types_id=st.seo_types_id) where st.seo_types_status='1' and s2p.products_id = '" . (int)$inner[1] . "'";
		if( !$this->set_id($params_query_raw, $seo_params_array) ) {
		  $this->assign_default($params_array, $value);
		}
		$flags_array['products_id'] = $inner[1];
		break;
	  case 'cPath':
		if( isset($flags_array['cpath']) || !tep_not_null($inner[1]) ) break;
		$path_flag = false;
		$path_link = explode('_', $inner[1]);
		$tmp_array = array();
		$depth = 0;
		$sort_order = 0;
		foreach ($path_link as $key2 => $value2 ) {
		  if(!$value2) continue;
		  if( !is_numeric($value2) ) {
			return 2;
		  }
		  $this->auto_builder($inner[0], $value2);
		  $params_query_raw = "select s2c.seo_name, st.sort_order, st.seo_types_linkage, st.seo_types_prefix, st.seo_types_handler from " . TABLE_SEO_TO_CATEGORIES . " s2c left join " . TABLE_SEO_TYPES . " st on (s2c.seo_types_id=st.seo_types_id) where st.seo_types_status='1' and s2c.categories_id = '" . (int)$value2 . "'";
		  $path_flag = $this->set_path($params_query_raw, $tmp_array, $depth, $sort_order);
		  if( !$path_flag ) {
			break;
		  }
		}
		if( $path_flag ) {
		  $final_path = implode(SEO_DEFAULT_INNER_SEPARATOR, $tmp_array);
		  $seo_params_array = array_merge( array($final_path => $sort_order), $seo_params_array);
		} else {
		  $this->assign_default($params_array, $value);
		}
		$flags_array['cpath'] = $inner[1];
		break;
	  case 'manufacturers_id':
		if( isset($flags_array['manufacturers_id']) || !tep_not_null($inner[1]) ) break;
		if( !is_numeric($inner[1]) ) {
		  return 2;
		}

		$this->auto_builder($inner[0], $inner[1]);
		$params_query_raw = "select s2m.seo_name, st.sort_order, st.seo_types_linkage, st.seo_types_prefix, st.seo_types_handler from " . TABLE_SEO_TO_MANUFACTURERS . " s2m left join " . TABLE_SEO_TYPES . " st on (s2m.seo_types_id=st.seo_types_id) where st.seo_types_status='1' and s2m.manufacturers_id = '" . (int)$inner[1] . "'";
		if( !$this->set_id($params_query_raw, $seo_params_array) ) {
		  $this->assign_default($params_array, $value);
		}
		$flags_array['manufacturers_id'] = $inner[1];
		break;
	  case 'page':
		if( isset($flags_array['page']) || !tep_not_null($inner[1]) ) break;
		if( !is_numeric($inner[1]) ) {
		  return 2;
		}
		$handler = '';
		if( !$this->handler_flag ) {
		  $handler = str_replace('.php', SEO_DEFAULT_INNER_SEPARATOR, $this->path);
		  $this->handler_flag = true;
		}
		$seo_params_array[$handler . 'p' . $inner[1]] = '99' . '_' . '-1';
		$flags_array['page'] = $inner[1];
		break;
//-MS- Use only if the articles manager is fully installed
/*
	  case 'articles_id':
		if( isset($flags_array['articles_id']) || !tep_not_null($inner[1]) ) break;
		if( !is_numeric($inner[1]) ) {
		  return 2;
		}
		$this->auto_builder($inner[0], $inner[1]);
		$params_query_raw = "select s2a.seo_name, st.sort_order, st.seo_types_linkage, st.seo_types_prefix, st.seo_types_handler from " . TABLE_SEO_TO_ARTICLES . " s2a left join " . TABLE_SEO_TYPES . " st on (s2a.seo_types_id=st.seo_types_id) where st.seo_types_status='1' and s2a.articles_id = '" . (int)$inner[1] . "'";
		if( !$this->set_id($params_query_raw, $seo_params_array) ) {
		  $this->assign_default($params_array, $value);
		}
		$flags_array['articles_id'] = $inner[1];
		break;
	  case 'tPath':
		if( isset($flags_array['tpath']) || !tep_not_null($inner[1]) ) break;
		$path_link = explode('_', $inner[1]);
		$tmp_array = array();
		$depth = 0;
		$sort_order = 0;
		foreach ($path_link as $key2 => $value2 ) {
		  if(!$value2) continue;
		  if( !is_numeric($value2) ) {
			return 2;
		  }
		  $this->auto_builder($inner[0], $value2);
		  $params_query_raw = "select s2t.seo_name, st.sort_order, st.seo_types_linkage, st.seo_types_prefix, st.seo_types_handler from " . TABLE_SEO_TO_TOPICS . " s2t left join " . TABLE_SEO_TYPES . " st on (s2t.seo_types_id=st.seo_types_id) where st.seo_types_status='1' and s2t.topics_id = '" . (int)$value2 . "'";
		  $path_flag = $this->set_path($params_query_raw, $tmp_array, $depth, $sort_order);
		  if( !$path_flag ) {
			break;
		  }
		}
		if( $path_flag ) {
		  $final_path = implode(SEO_DEFAULT_INNER_SEPARATOR, $tmp_array);
		  $seo_params_array = array_merge( array($final_path => $sort_order), $seo_params_array);
		} else {
		  $this->assign_default($params_array, $value);
		}
		$flags_array['tpath'] = $inner[1];
		break;
*/
//-MS- Use only if the articles manager is fully installed EOM
	  default:
		$this->assign_default($params_array, $value);
		$flags_array['other'] = true;
		break;
	}
  }
  if( count($seo_params_array) ) {
	$this->resolve_linkage($seo_params_array);
	asort($seo_params_array, SORT_NUMERIC);
	$seo_params_array = array_keys($seo_params_array);
	$params_array = array_merge($seo_params_array, $params_array);
	$result = 1;
  }
  $query = implode('&', $params_array);
  $other = $flags_array['other'];
  return $result;
}

function resolve_linkage(&$seo_params_array) {
  $tmp_array = array();
  foreach($seo_params_array as $key => $value) {
	list($sort, $link) = split("_", $value, 2);
	$seo_params_array[$key] = $sort;
	$tmp_array[$key] = $link;
  }
  asort($tmp_array, SORT_NUMERIC);
  foreach($tmp_array as $key => $value) {
	if( $value < 0 )
	  continue;

	if( !isset($reduce) ) {
	  $reduce = $value;
	  continue;
	}
	if($reduce != $value) {
	  unset($seo_params_array[$key]);
	}
  }
}


function auto_builder($entity, $id) {
  if( SEO_AUTO_BUILDER == 'false' )
	return;
//Perso
$seo_lang_code = '4';

  switch($entity) {
	case 'products_id':
	  $check_query = tep_db_query("select products_id from " . TABLE_SEO_TO_PRODUCTS . " where products_id = '" . (int)$id . "'");
	  if( tep_db_num_rows($check_query) ) 
		return;
	  //$name_query = tep_db_query("select products_name as name from " . TABLE_PRODUCTS_DESCRIPTION . " where products_id = '" . (int)$id . "' and language_id = '1'");
//Perso
$name_query = tep_db_query("select products_name as name from " . TABLE_PRODUCTS_DESCRIPTION . " where products_id = '" . (int)$id . "' and language_id = '".$seo_lang_code."'");

	  if( $names_array = tep_db_fetch_array($name_query) ) {
		$types_query = tep_db_query("select seo_types_id from " . TABLE_SEO_TYPES . " where seo_types_class = 'seo_products'");
		if( $types_array = tep_db_fetch_array($types_query) ) {
		  $seo_name = $this->create_safe_name($names_array['name']);
		  $sql_data_array = array(
								  'seo_types_id' => (int)$types_array['seo_types_id'],
								  'products_id' => (int)$id,
								  'seo_name' => tep_db_prepare_input($seo_name),
								  );
		  tep_db_perform(TABLE_SEO_TO_PRODUCTS, $sql_data_array, 'insert');
		}
	  }
	  break;
	case 'cPath':
	  $check_query = tep_db_query("select categories_id from " . TABLE_SEO_TO_CATEGORIES . " where categories_id = '" . (int)$id . "'");
	  if( tep_db_num_rows($check_query) ) 
		return;
	  //$name_query = tep_db_query("select categories_name as name from " . TABLE_CATEGORIES_DESCRIPTION . " where categories_id = '" . (int)$id . "' and language_id = '4'");
//Perso
$name_query = tep_db_query("select categories_name as name from " . TABLE_CATEGORIES_DESCRIPTION . " where categories_id = '" . (int)$id . "' and language_id = '".$seo_lang_code."'");

	  if( $names_array = tep_db_fetch_array($name_query) ) {
		$types_query = tep_db_query("select seo_types_id from " . TABLE_SEO_TYPES . " where seo_types_class = 'seo_categories'");
		if( $types_array = tep_db_fetch_array($types_query) ) {
		  $seo_name = $this->create_safe_name($names_array['name']);
		  $sql_data_array = array(
								  'seo_types_id' => (int)$types_array['seo_types_id'],
								  'categories_id' => (int)$id,
								  'seo_name' => tep_db_prepare_input($seo_name),
								  );
		  tep_db_perform(TABLE_SEO_TO_CATEGORIES, $sql_data_array, 'insert');
		}
	  }
	  break;
	case 'manufacturers_id':
	  $check_query = tep_db_query("select manufacturers_id from " . TABLE_SEO_TO_MANUFACTURERS . " where manufacturers_id = '" . (int)$id . "'");
	  if( tep_db_num_rows($check_query) ) 
		return;
	  $name_query = tep_db_query("select manufacturers_name as name from " . TABLE_MANUFACTURERS . " where manufacturers_id = '" . (int)$id . "'");
	  if( $names_array = tep_db_fetch_array($name_query) ) {
		$types_query = tep_db_query("select seo_types_id from " . TABLE_SEO_TYPES . " where seo_types_class = 'seo_manufacturers'");
		if( $types_array = tep_db_fetch_array($types_query) ) {
		  $seo_name = $this->create_safe_name($names_array['name']);
		  $sql_data_array = array(
								  'seo_types_id' => (int)$types_array['seo_types_id'],
								  'manufacturers_id' => (int)$id,
								  'seo_name' => tep_db_prepare_input($seo_name),
								  );
		  tep_db_perform(TABLE_SEO_TO_MANUFACTURERS, $sql_data_array, 'insert');
		}
	  }
	  break;

	case 'articles_id':
	  $check_query = tep_db_query("select articles_id from " . TABLE_SEO_TO_ARTICLES . " where articles_id = '" . (int)$id . "'");
	  if( tep_db_num_rows($check_query) ) 
		return;
	  //$name_query = tep_db_query("select articles_name as name from " . TABLE_ARTICLES_DESCRIPTION . " where articles_id = '" . (int)$id . "' and language_id = '4'");
//Perso
$name_query = tep_db_query("select articles_name as name from " . TABLE_ARTICLES_DESCRIPTION . " where articles_id = '" . (int)$id . "' and language_id = '".$seo_lang_code."'");

	  if( $names_array = tep_db_fetch_array($name_query) ) {
		$types_query = tep_db_query("select seo_types_id from " . TABLE_SEO_TYPES . " where seo_types_class = 'seo_articles'");
		if( $types_array = tep_db_fetch_array($types_query) ) {
		  $seo_name = $this->create_safe_name($names_array['name']);
		  $sql_data_array = array(
								  'seo_types_id' => (int)$types_array['seo_types_id'],
								  'products_id' => (int)$id,
								  'seo_name' => tep_db_prepare_input($seo_name),
								  );
		  tep_db_perform(TABLE_SEO_TO_ARTICLES, $sql_data_array, 'insert');
		}
	  }
	  break;
	case 'tPath':
	  $check_query = tep_db_query("select topics_id from " . TABLE_SEO_TO_TOPICS . " where topics_id = '" . (int)$id . "'");
	  if( tep_db_num_rows($check_query) ) 
		return;
	  //$name_query = tep_db_query("select topcis_name as name from " . TABLE_TOPICS_DESCRIPTION . " where topics_id = '" . (int)$id . "' and language_id = '4'");
//Perso
$name_query = tep_db_query("select topcis_name as name from " . TABLE_TOPICS_DESCRIPTION . " where topics_id = '" . (int)$id . "' and language_id = '".$seo_lang_code."'");

	  if( $names_array = tep_db_fetch_array($name_query) ) {
		$types_query = tep_db_query("select seo_types_id from " . TABLE_SEO_TYPES . " where seo_types_class = 'seo_topics'");
		if( $types_array = tep_db_fetch_array($types_query) ) {
		  $seo_name = $this->create_safe_name($names_array['name']);
		  $sql_data_array = array(
								  'seo_types_id' => (int)$types_array['seo_types_id'],
								  'topics_id' => (int)$id,
								  'seo_name' => tep_db_prepare_input($seo_name),
								  );
		  tep_db_perform(TABLE_SEO_TO_TOPICS, $sql_data_array, 'insert');
		}
	  }
	  break;
	default:
	  break;
  }
}

function set_id($query_raw, &$seo_params_array) {
  $result = $handler = false;
  $params_query = tep_db_query($query_raw);
  if( $entry = tep_db_fetch_array($params_query) ) {
	if( tep_not_null($entry['seo_types_handler']) ) {
	  $handler_array = explode(',', $entry['seo_types_handler']);
	  foreach($handler_array as $key => $value ) {
		$value = trim($value);
		if( $this->path == $value ) {
		  $handler = $value;
		  break;
		}
	  }
	}
	if( $handler && !$this->handler_flag) {
	  $handler = str_replace('.php', SEO_DEFAULT_INNER_SEPARATOR, $handler);
	  $seo_params_array[$handler . $entry['seo_name']] = $entry['sort_order'] . '_' . $entry['seo_types_linkage'];
	  $this->handler_flag = true;
	} else {
	  $seo_params_array[$entry['seo_types_prefix'] . $entry['seo_name']] = $entry['sort_order'] . '_' . $entry['seo_types_linkage'];
	}
	$this->handler_flag = $result = true;
  }
  return $result;
}

function set_path($query_raw, &$tmp_array, &$depth, &$sort_order) {
  $result = $handler = false;
  $params_query = tep_db_query($query_raw);
  if( $entry = tep_db_fetch_array($params_query) ) {
	if( !$depth ) {
	  if( tep_not_null($entry['seo_types_handler']) ) {
		$handler_array = explode(',', $entry['seo_types_handler']);
		foreach($handler_array as $key => $value) {
		  if( $this->path == $value ) {
			$handler = $value;
			break;
		  }
		}
	  }
	  if( $handler && !$this->handler_flag ) {
		$handler = str_replace('.php', SEO_DEFAULT_INNER_SEPARATOR, $handler);
		$tmp_array[] = $handler . $entry['seo_name'];
	  } else {
		$tmp_array[] = $entry['seo_types_prefix'] . $entry['seo_name'];
	  }
	  $sort_order = $entry['sort_order'] . '_' . $entry['seo_types_linkage'];
	} else {
	  $tmp_array[] = $entry['seo_name'];
	}
	$depth++;
	$this->handler_flag = $result = true;
  }
  return $result;
}

function assign_default(&$params_array, $value) {
  $value = $this->create_safe_string($value);
  $params_array[$value] = $value;
}

function exclude_script() {
  // Make sure this is a php script otherwise exclude it.
  if( strlen($this->path) < 5 || substr($this->path, -4, 4) != '.php') {
	return true;
  }
  $result = false;
  $key = md5($this->path);

  $check_query = tep_db_query("select seo_exclude_key from " . TABLE_SEO_EXCLUDE . " where seo_exclude_key = '" . tep_db_input($key) . "'");
  if( tep_db_num_rows($check_query) ) {
	 return true;
  }

  $this->params_array = explode('&', $this->query );
  return $result;
}

// Validate REQUEST_URI in case we got a redirect from a server script. May needed with some servers
function validate_uri(&$seo_url) {
  global $g_relpath; 
  $request_uri = explode('?', $_SERVER['REQUEST_URI']);
  $self = basename($_SERVER['PHP_SELF']);
  $self_count = strlen($self);
  if( is_array($request_uri) && isset($request_uri[1]) && strlen($request_uri[0]) > $self_count && $self == substr($request_uri[0], -$self_count, $self_count) ) {
	$this->params_array = explode('&', $request_uri[1]);
	if( is_array($this->params_array) ) {
	  $seo_url = $_SERVER['REQUEST_URI'] = $this->params_array[0];
	  unset($this->params_array[0]);
	  $query_string = implode('&',$this->params_array);
	  if( $query_string != '' ) {
		$seo_url .= '?' . $query_string;
		$_SERVER['REQUEST_URI'] = $seo_url;
	  }
	  // Rectify seo url
	  $seo_url = $g_relpath . $_SERVER['REQUEST_URI'];
	}
  }
}

function eliminate_session($remove_name=false) {
  if( !$remove_name ) {
	$remove_name = tep_session_name();
  }
  if( is_array($this->params_array) ) {
	for($i=0, $j=count($this->params_array); $i<$j; $i++ ) {
	  if(stristr($this->params_array[$i], $remove_name) ) {
		unset($this->params_array[$i]);
	  }
	}
  }
}
 }
?>

Share this post


Link to post
Share on other sites

Ok it works to a certain extend.

www.mobiliparts.com/apple-ipod/support-smartphone-telephone-mobile-pour-voiture.htm

where the link is generated with the french name. But if I change the language to english the link generate remains in french. Because SEO-G only holds one name for each products_id you see?

 

And in order to accommodate it, I would need to change the framework such that SEO_TO_PRODUCTS and other tables have an extra column to specify the language.

Edited by enigma1

Share this post


Link to post
Share on other sites

I'm having some trouble with SEO-G and getting it to work on product_reviews_info.php

 

All the other pages seem to work fantastically except this one.

Share this post


Link to post
Share on other sites
I'm having some trouble with SEO-G and getting it to work on product_reviews_info.php

 

All the other pages seem to work fantastically except this one.

Ok please elaborate what doesn't work. Do you have a link to a review page?

Share this post


Link to post
Share on other sites

Sorry emigma1, it was quite a brief problem description.

 

basically, I'm getting this:

http://www.mydomain.com/oscomm/product_rev...mp;reviews_id=1

 

in the address bar instead of, what I can assume should be being handled by seo_products.php (not sure what it should be).

 

the seo_products.php file has been untouched.

 

the setup in the osC admin G-Types is default as the majority of the pages worked right away except product_reviews_info.php

Share this post


Link to post
Share on other sites
Sorry emigma1, it was quite a brief problem description.

 

basically, I'm getting this:

http://www.mydomain.com/oscomm/product_rev...mp;reviews_id=1

 

in the address bar instead of, what I can assume should be being handled by seo_products.php (not sure what it should be).

 

the seo_products.php file has been untouched.

 

the setup in the osC admin G-Types is default as the majority of the pages worked right away except product_reviews_info.php

ah yes, now I understand, so by default SEO-G will use safe mode (you can switch safe mode off from the admin as long as you know the details on what will happen). That means if any of the parameters within an osC link cannot be translated (reviews_id in this case) the link is not altered. The session id is not taken into the account by SEO-G is always discarded for obvious reasons. So now if there was a class for reviews like there is for manufacturers for instance the parameter would be decoded.

 

Since you're asking this, what would be the best way to display the reviews with the link in your opinion? What would you like to see there? The name of the person who did the review?

Edited by enigma1

Share this post


Link to post
Share on other sites

Hi enigma1.

 

Thanks for your assistance.

 

I think the best way to do a review in a more friendly URL would be to maybe fake a reviews directory and then put the product name after it, a la:

http://www.mydomain.com/catalog/reviews/&l...t_name>.html

 

I'm not sure how easy that would be to do, but it would look much nicer.

 

Have you considered adding META tag functionality to SEO-G? It's a very impressive contribution and I think that META tags could be the proverbial icing on the cake.

Share this post


Link to post
Share on other sites
Hi enigma1.

 

Thanks for your assistance.

 

I think the best way to do a review in a more friendly URL would be to maybe fake a reviews directory and then put the product name after it, a la:

http://www.mydomain.com/catalog/reviews/&a...t_name>.html

 

I'm not sure how easy that would be to do, but it would look much nicer.

 

Have you considered adding META tag functionality to SEO-G? It's a very impressive contribution and I think that META tags could be the proverbial icing on the cake.

 

The products_id will be decoded once the reviews_id is decoded. But you need a modifier to distinguish the various reviews. In other words the same product can have multiple reviews.

 

http://www.mydomain.com/catalog/reviews/&l...t_name>.html

http://www.mydomain.com/catalog/reviews/&l...t_name>.html

http://www.mydomain.com/catalog/reviews/&l...t_name>.html

.....

 

So the links will end up being the same you see?. Undecoded this can be distinguished by the reviews_id. But what will be a better method to do that? By a single letter followed by the id number or by the poster's name?

Share this post


Link to post
Share on other sites
I attempted to apply this contribution but I had quite a few problems, not the least of which being that I got "file not found" when the seo addresses were active. Being responsible, I had backed up my files and database, so I attempted to return them to what they had been before the aplication of seo-g. Now I get this error message at the head of every page of the store (similar to messages I got immediately following the installation of seo-g):

 

Warning: session_start(): Cannot send session cookie - headers already sent by (output started at /home/content/s/p/e/specterstudios/html/store/catalog/includes/filenames.php:126) in /home/content/s/p/e/specterstudios/html/store/catalog/includes/functions/sessions.php on line 97

 

Warning: session_start(): Cannot send session cache limiter - headers already sent (output started at /home/content/s/p/e/specterstudios/html/store/catalog/includes/filenames.php:126) in /home/content/s/p/e/specterstudios/html/store/catalog/includes/functions/sessions.php on line 97

 

And I get this message when I try to make any change from the admin area (similar to messages I got immediately following the installation of seo-g):

 

Warning: Cannot modify header information - headers already sent by (output started at /home/content/s/p/e/specterstudios/html/store/catalog/admin/includes/languages/english.php:640) in /home/content/s/p/e/specterstudios/html/store/catalog/admin/includes/functions/general.php on line 23

 

Luckily, the change usually goes through after I back out, but I would still prefer not to get these messages at all. What can I do to rectify this? If more information is needed, I will do my best to provide it.

 

I re-installed this mod, and it works now. Hurray! The first post you pointed me to really helped. I found that the .htaccess file was very finicky about how it was saved. However, I still get the same warning reports at the tops of the pages. The non-index pages of the store only give me the second error:

 

Warning: session_start(): Cannot send session cache limiter - headers already sent (output started at /home/content/s/p/e/specterstudios/html/store/catalog/includes/filenames.php:126) in /home/content/s/p/e/specterstudios/html/store/catalog/includes/functions/sessions.php on line 97

 

And I still get the "Cannot modify header information" any time I make a change in my admin area. I tried commenting out the offending line (line 23 - general.php), and it would just take me to a blank page.

 

What is really dumbfounding me is that none of the files mentioned in the warnings were changed or replaced during the installation, but I didn't get these warning messages ever before. Do you have any ideas what might be causing this or how I should fix it?

 

Here is my site if it helps: http://www.specterstore.com/store

 

Also, though I get seo urls now, I get "?osCsid=" (minus the quotes) appended to each url with a line of numbers and letters following it. Is there a way to eliminate this?

 

This is a fantastic contribution, and I can see that you are very dedicated to improving it and helping individuals to impliment it. I want to thank you for that.

Share this post


Link to post
Share on other sites
I re-installed this mod, and it works now. Hurray! The first post you pointed me to really helped. I found that the .htaccess file was very finicky about how it was saved. However, I still get the same warning reports at the tops of the pages. The non-index pages of the store only give me the second error:

 

Warning: session_start(): Cannot send session cache limiter - headers already sent (output started at /home/content/s/p/e/specterstudios/html/store/catalog/includes/filenames.php:126) in /home/content/s/p/e/specterstudios/html/store/catalog/includes/functions/sessions.php on line 97

 

And I still get the "Cannot modify header information" any time I make a change in my admin area. I tried commenting out the offending line (line 23 - general.php), and it would just take me to a blank page.

You need to use a regular editor if you want to find a good one check the wikipedia.org and sourceforge.net domains. (search for text editor or similar keywords). They have good info.

 

As of the particular error I would start by checking your catalog\includes\filenames.php file. Check for whitespace at the beginning and end of file. Make sure no spaces exist before the <?php tag and after the ?> closing tag.

Edited by enigma1

Share this post


Link to post
Share on other sites
You need to use a regular editor if you want to find a good one check the wikipedia.org and sourceforge.net domains. (search for text editor or similar keywords). They have good info.

 

As of the particular error I would start by checking your catalog\includes\filenames.php file. Check for whitespace at the beginning and end of file. Make sure no spaces exist before the <?php tag and after the ?> closing tag.

 

I checked. I had two returns after the ?> so I deleted those and resaved. No change.

Share this post


Link to post
Share on other sites
I checked. I had two returns after the ?> so I deleted those and resaved. No change.

Yes there is a change. Now it shows the html_output.php, repeat the procedure till it gets clean. See? The filenames.php seems to be good now.

Share this post


Link to post
Share on other sites
Have you considered adding META tag functionality to SEO-G? It's a very impressive contribution and I think that META tags could be the proverbial icing on the cake.

Forgot to answer this part:

 

If I make it that far, it will be a different module. It's not an easy task although I have some code separately and experimenting with it at this point. It uses AI 100%, in other words you do not enter keywords per product, category, page etc, but instead it uses dictionaries. Keywords are automatically generated. The seo results for metatags as far I've tested show up > 90% relevancy.

 

I am still working with the relationships between the seo tables, because each page must be exposed coherently ie the link matches the keywords, the keywords match the page content, the title matches the link the meta-tag short description matches the main content and you can have multiple modules with each page. And all this needs to be automatic and reasonable. Like say featured products and reviews beneath the product's description have to be taken into account.

 

And even if somehow have everything ready, I have to think of a way to make this module practical for integration. I don't want to write thousands of documentation lines and modify every osc file.

 

But its development is very slow, as I have little time left to manage and support every module. There are also other priorities like the different classes to support: authors for the articles manager, information pages, the links manager, xml/rss products/feeds, froogle, multilanguages things like that. And for every feature I add, I need to take care of the side-effects and they're quite a few.

Share this post


Link to post
Share on other sites
Also, though I get seo urls now, I get "?osCsid=" (minus the quotes) appended to each url with a line of numbers and letters following it. Is there a way to eliminate this?

 

This is a fantastic contribution, and I can see that you are very dedicated to improving it and helping individuals to impliment it. I want to thank you for that.

If the osCsid does not go away after a couple of clicks it means session cookies don't work. If you're not blocking them with the browser, then your configure.php file is not setup properly. But this is not SEO-G related.

Share this post


Link to post
Share on other sites
Yes there is a change. Now it shows the html_output.php, repeat the procedure till it gets clean. See? The filenames.php seems to be good now.

 

You rock! Problems solved. That is all for now.

Share this post


Link to post
Share on other sites
You rock! Problems solved. That is all for now.

 

 

 

 

Hello every one,

 

I installed SEO-G 1.16 but when I go to osc admin/configuration/SEO-G configuration I have couple of each title for the whole titles like the following:

 

SEO-G Master Switch True

SEO-G Master Switch True

 

SEO-G Extension .html

SEO-G Extension .html

 

SEO-G Error Header 301

SEO-G Error Header 301

 

And going on the whole list, any reason why is that and how to correct this ?

 

Thanks for your assistance

Ahmed

Share this post


Link to post
Share on other sites
Hello every one,

 

I installed SEO-G 1.16 but when I go to osc admin/configuration/SEO-G configuration I have couple of each title for the whole titles like the following:

 

SEO-G Master Switch True

SEO-G Master Switch True

 

SEO-G Extension .html

SEO-G Extension .html

 

SEO-G Error Header 301

SEO-G Error Header 301

 

And going on the whole list, any reason why is that and how to correct this ?

 

Thanks for your assistance

Ahmed

yes, you probably re-entered the dbase configuration switches. Use phpmyadmin or the total configuration (v1.01) contribution, to get rid of the duplicated fields. I find the later easier to use for this purpose, as it lists all duplicated fields and you can get rid of them with a couple of clicks.

http://www.oscommerce.com/community/contributions,5040

Share this post


Link to post
Share on other sites
yes, you probably re-entered the dbase configuration switches. Use phpmyadmin or the total configuration (v1.01) contribution, to get rid of the duplicated fields. I find the later easier to use for this purpose, as it lists all duplicated fields and you can get rid of them with a couple of clicks.

http://www.oscommerce.com/community/contributions,5040

 

 

 

Mark,

 

Thanks for your help, very kind of you.

 

I installed the Total configuration_1.02 and It worked perfectly, just before deleting the SE-G duplicates I have a question:

 

As you can see at the picture below, the duplicates have different ID’s , do I just delete any one of them or the ID number does matter ?

 

 

Duplicate.jpg

 

 

There is a license file with the contributin, what to do with this file ? do I have to keep it at the website’s root directory?

 

Thanks again for your assistance

Regards

Ahmed

Share this post


Link to post
Share on other sites

no the id doesn't matter. The license is the standard GPL v2.0 and should be included with every contribution stating how the files can be distributed/used.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×