[phpBB Debug] PHP Warning: in file [ROOT]/includes/crs/crs_misc_functions.php on line 37: mime_content_type(): Empty filename or path
[phpBB Debug] PHP Warning: in file [ROOT]/includes/crs/crs_misc_functions.php on line 37: mime_content_type(): Empty filename or path
Zen Cart 源代码 seo.url.php

Zen Cart 源代码 seo.url.php




下载文件

文件名: seo.url.php
文件类型: PHP文件
文件大小: 45.94 KiB
MD5: b860713e82bccd141ca417eab89e39b0

seo.url.php - 关闭高亮
  1. <?php
  2. /*
  3.     +----------------------------------------------------------------------+
  4.     |   Ultimate SEO URLs For Zen Cart, version 2.101                        |
  5.     +----------------------------------------------------------------------+
  6.     |                                                                      |
  7.     |   Derrived from Ultimate SEO URLs v2.1 for osCommerce by Chemo         |
  8.     |                                                                      |
  9.     |   Portions Copyright 2005, Joshua Dechant                              |
  10.     |                                                                      |
  11.     |   Portions Copyright 2005, Bobby Easland                               |
  12.     |                                                                      |
  13.     |   Portions Copyright 2003 The zen-cart developers                      |
  14.     |                                                                      |
  15.     +----------------------------------------------------------------------+
  16.     | This source file is subject to version 2.0 of the GPL license,       |
  17.     | that is bundled with this package in the file LICENSE, and is        |
  18.     | available through the world-wide-web at the following url:           |
  19.     | http://www.zen-cart.com/license/2_0.txt.                             |
  20.     | If you did not receive a copy of the zen-cart license and are unable |
  21.     | to obtain it through the world-wide-web, please send a note to       |
  22.     | license@zen-cart.com so we can mail you a copy immediately.          |
  23.     +----------------------------------------------------------------------+
  24. */
  25.  
  26.     require_once(dirname(__FILE__) . '/seo.install.php');
  27.  
  28.     class SEO_URL{
  29.         var $cache;
  30.         var $languages_id;
  31.         var $attributes;
  32.         var $base_url;
  33.         var $base_url_ssl;
  34.         var $reg_anchors;
  35.         var $cache_query;
  36.         var $cache_file;
  37.         var $data;
  38.         var $need_redirect;
  39.         var $is_seopage;
  40.         var $uri;
  41.         var $real_uri;
  42.         var $uri_parsed;
  43.         var $db;
  44.         var $installer;
  45.  
  46.         function SEO_URL($languages_id=''){
  47.             global $session_started;
  48.  
  49.             $this->installer = &new SEO_URL_INSTALLER();
  50.  
  51.             $this->db = &$GLOBALS['db'];
  52.  
  53.             if ($languages_id == '') $languages_id = $_SESSION['languages_id'];
  54.  
  55.             $this->languages_id = (int)$languages_id;
  56.  
  57.             $this->data = array();
  58.  
  59.             $seo_pages = array(
  60.                 FILENAME_DEFAULT,
  61.                 FILENAME_PRODUCT_INFO,
  62.                 FILENAME_POPUP_IMAGE,
  63.                 FILENAME_PRODUCT_REVIEWS,
  64.                 FILENAME_PRODUCT_REVIEWS_INFO,
  65.                 FILENAME_EZPAGES,
  66.             );
  67.  
  68.             // News & Article Manager SEO support
  69.             if (defined('FILENAME_NEWS_INDEX')) $seo_pages[] = FILENAME_NEWS_INDEX;
  70.             if (defined('FILENAME_NEWS_ARTICLE')) $seo_pages[] = FILENAME_NEWS_ARTICLE;
  71.             if (defined('FILENAME_NEWS_COMMENTS')) $seo_pages[] = FILENAME_NEWS_COMMENTS;
  72.             if (defined('FILENAME_NEWS_ARCHIVE')) $seo_pages[] = FILENAME_NEWS_ARCHIVE;
  73.             if (defined('FILENAME_NEWS_RSS')) $seo_pages[] = FILENAME_NEWS_RSS;
  74.  
  75.             // Info Manager (Open Operations)
  76.             if (defined('FILENAME_INFO_MANAGER')) $seo_pages[] = FILENAME_INFO_MANAGER;
  77.  
  78.             $this->attributes = array(
  79.                 'PHP_VERSION' => PHP_VERSION,
  80.                 'SESSION_STARTED' => $session_started,
  81.                 'SID' => (defined('SID') && $this->not_null(SID) ? SID : ''),
  82.                 'SEO_ENABLED' => defined('SEO_ENABLED') ? SEO_ENABLED : 'false',
  83.                 'SEO_ADD_CPATH_TO_PRODUCT_URLS' => defined('SEO_ADD_CPATH_TO_PRODUCT_URLS') ? SEO_ADD_CPATH_TO_PRODUCT_URLS : 'false',
  84.                 'SEO_ADD_CAT_PARENT' => defined('SEO_ADD_CAT_PARENT') ? SEO_ADD_CAT_PARENT : 'true',
  85.                 'SEO_URLS_USE_W3C_VALID' => defined('SEO_URLS_USE_W3C_VALID') ? SEO_URLS_USE_W3C_VALID : 'true',
  86.                 'USE_SEO_CACHE_GLOBAL' => defined('USE_SEO_CACHE_GLOBAL') ? USE_SEO_CACHE_GLOBAL : 'false',
  87.                 'USE_SEO_CACHE_PRODUCTS' => defined('USE_SEO_CACHE_PRODUCTS') ? USE_SEO_CACHE_PRODUCTS : 'false',
  88.                 'USE_SEO_CACHE_CATEGORIES' => defined('USE_SEO_CACHE_CATEGORIES') ? USE_SEO_CACHE_CATEGORIES : 'false',
  89.                 'USE_SEO_CACHE_MANUFACTURERS' => defined('USE_SEO_CACHE_MANUFACTURERS') ? USE_SEO_CACHE_MANUFACTURERS : 'false',
  90.                 'USE_SEO_CACHE_ARTICLES' => defined('USE_SEO_CACHE_ARTICLES') ? USE_SEO_CACHE_ARTICLES : 'false',
  91.                 'USE_SEO_CACHE_INFO_PAGES' => defined('USE_SEO_CACHE_INFO_PAGES') ? USE_SEO_CACHE_INFO_PAGES : 'false',
  92.                 'USE_SEO_CACHE_EZ_PAGES' => defined('USE_SEO_CACHE_EZ_PAGES') ? USE_SEO_CACHE_EZ_PAGES : 'false',
  93.                 'USE_SEO_REDIRECT' => defined('USE_SEO_REDIRECT') ? USE_SEO_REDIRECT : 'false',
  94.                 'SEO_REWRITE_TYPE' => defined('SEO_REWRITE_TYPE') ? SEO_REWRITE_TYPE : 'false',
  95.                 'SEO_URLS_FILTER_SHORT_WORDS' => defined('SEO_URLS_FILTER_SHORT_WORDS') ? SEO_URLS_FILTER_SHORT_WORDS : 'false',
  96.                 'SEO_CHAR_CONVERT_SET' => defined('SEO_CHAR_CONVERT_SET') ? $this->expand(SEO_CHAR_CONVERT_SET) : 'false',
  97.                 'SEO_REMOVE_ALL_SPEC_CHARS' => defined('SEO_REMOVE_ALL_SPEC_CHARS') ? SEO_REMOVE_ALL_SPEC_CHARS : 'false',
  98.                 'SEO_PAGES' => $seo_pages,
  99.                 'SEO_INSTALLER' => $this->installer->attributes
  100.             );
  101.  
  102.             $this->base_url = HTTP_SERVER;
  103.             $this->base_url_ssl = HTTPS_SERVER;
  104.             $this->cache = array();
  105.  
  106.             $this->reg_anchors = array(
  107.                 'products_id' => '-p-',
  108.                 'cPath' => '-c-',
  109.                 'manufacturers_id' => '-m-',
  110.                 'pID' => '-pi-',
  111.                 'products_id_review' => '-pr-',
  112.                 'products_id_review_info' => '-pri-',
  113.  
  114.                 // News & Article Manager SEO support
  115.                 'news_article_id' => '-a-',
  116.                 'news_comments_article_id' => '-a-',
  117.                 'news_dates' => '/',
  118.                 'news_archive_dates' => '/archive/',
  119.                 'news_rss_feed' => '/rss',
  120.  
  121.                 // Info Manager (Open Operations)
  122.                 'info_manager_page_id' => '-i-',
  123.  
  124.                 // EZ-Pages SEO support
  125.                 'id' => '-ezp-',
  126.             );
  127.  
  128.             if ($this->attributes['USE_SEO_CACHE_GLOBAL'] == 'true'){
  129.                 $this->cache_file = 'seo_urls_v2_';
  130.                 $this->cache_gc();
  131.                 if ( $this->attributes['USE_SEO_CACHE_PRODUCTS'] == 'true' ) $this->generate_products_cache();
  132.                 if ( $this->attributes['USE_SEO_CACHE_CATEGORIES'] == 'true' ) $this->generate_categories_cache();
  133.                 if ( $this->attributes['USE_SEO_CACHE_MANUFACTURERS'] == 'true' ) $this->generate_manufacturers_cache();
  134.                 if ( $this->attributes['USE_SEO_CACHE_ARTICLES'] == 'true' && defined('TABLE_NEWS_ARTICLES_TEXT')) $this->generate_news_articles_cache();
  135.                 if ( $this->attributes['USE_SEO_CACHE_INFO_PAGES'] == 'true' && defined('TABLE_INFO_MANAGER')) $this->generate_info_manager_cache();
  136.                 if ( $this->attributes['USE_SEO_CACHE_EZ_PAGES'] == 'true' ) $this->generate_ezpages_cache();
  137.             }
  138.  
  139.             if ($this->attributes['USE_SEO_REDIRECT'] == 'true'){
  140.                 $this->check_redirect();
  141.             } # end if
  142.         } # end constructor
  143.  
  144.         function href_link($page = '', $parameters = '', $connection = 'NONSSL', $add_session_id = true, $static = false, $use_dir_ws_catalog = true) {
  145.             // don't rewrite when disabled
  146.             // don't rewrite images, css, js, xml, real html files, etc
  147.             if ( ($this->attributes['SEO_ENABLED'] == 'false') || (preg_match('/(.+)\.(html?|xml|css|js|png|jpe?g|gif|bmp|tiff?|ico|gz|zip|rar)$/i', $page)) ) {
  148.                 return $this->stock_href_link($page, $parameters, $connection, $add_session_id, true, $static, $use_dir_ws_catalog);
  149.             }
  150.       // don't rewrite the paypal IPN notify url
  151.       if ($page == 'ipn_main_handler.php') {
  152.        return $this->stock_href_link($page, $parameters, $connection, $add_session_id, true, $static, $use_dir_ws_catalog);
  153.       }
  154.       // don't rewrite the zhifubao ATN notify url
  155.       if ($page == 'atn_main_handler.php') {
  156.        return $this->stock_href_link($page, $parameters, $connection, $add_session_id, true, $static, $use_dir_ws_catalog);
  157.       }
  158.  
  159.             if ((!in_array($page, $this->attributes['SEO_PAGES'])) || (($page == FILENAME_DEFAULT) && (!preg_match('/(cpath|manufacturers_id)/i', $parameters)))) {
  160.                 if ($page == FILENAME_DEFAULT) {
  161.                     $page = '';
  162.                 } else {
  163.                     $page = $page . '.html';
  164.                 }
  165.             }
  166.  
  167.             if ($connection == 'NONSSL') {
  168.                 $link = $this->base_url;
  169.             } elseif ($connection == 'SSL') {
  170.                 if (ENABLE_SSL == 'true') {
  171.                     $link = $this->base_url_ssl ;
  172.                 } else {
  173.                     $link = $this->base_url;
  174.                 }
  175.             }
  176.  
  177.       if ($use_dir_ws_catalog) {
  178.         if ($connection == 'SSL' && ENABLE_SSL == 'true') {
  179.           $link .= DIR_WS_HTTPS_CATALOG;
  180.         } else {
  181.           $link .= DIR_WS_CATALOG;
  182.         }
  183.       }
  184.  
  185.             if (strstr($page, '?')) {
  186.                 $separator = '&';
  187.             } else {
  188.                 $separator = '?';
  189.             }
  190.  
  191.             if ($this->not_null($parameters)) {
  192.                 $link .= $this->parse_parameters($page, $parameters, $separator);
  193.             } else {
  194.                 // support SEO pages with no parameters
  195.                 switch ($page) {
  196.                     case FILENAME_NEWS_RSS:
  197.                         $link .= $this->make_url($page, FILENAME_NEWS_INDEX, 'news_rss_feed', '', '.xml', $separator);
  198.                         break;
  199.                     case FILENAME_NEWS_ARCHIVE:
  200.                         $link .= $this->make_url($page, FILENAME_NEWS_INDEX, 'news_archive_dates', '', '', $separator);
  201.                         break;
  202.                     case FILENAME_NEWS_INDEX:
  203.                         $link .= $this->make_url($page, FILENAME_NEWS_INDEX, 'news_dates', '', '', $separator);
  204.                         break;
  205.  
  206.                     default:
  207.                         $link .= $page;
  208.                         break;
  209.                 }
  210.             }
  211.  
  212.             $link = $this->add_sid($link, $add_session_id, $connection, $separator);
  213.  
  214.             switch($this->attributes['SEO_URLS_USE_W3C_VALID']){
  215.                 case 'true':
  216.                     if (!isset($_SESSION['customer_id']) && defined('ENABLE_PAGE_CACHE') && ENABLE_PAGE_CACHE == 'true' && class_exists('page_cache')){
  217.                         return $link;
  218.                     } else {
  219.                         return htmlspecialchars(utf8_encode($link));
  220.                     }
  221.                     break;
  222.                 case 'false':
  223.                 default:
  224.                     return $link;
  225.                     break;
  226.             }
  227.         } # end function
  228.  
  229.         function stock_href_link($page = '', $parameters = '', $connection = 'NONSSL', $add_session_id = true, $search_engine_safe = true, $static = false, $use_dir_ws_catalog = true) {
  230.             global $request_type, $session_started, $http_domain, $https_domain;
  231.  
  232.             if (!$this->not_null($page)) {
  233.                 die('</td></tr></table></td></tr></table><br /><br /><strong class="note">Error!<br /><br />Unable to determine the page link!</strong><br /><br />');
  234.             }
  235.  
  236.             if ($connection == 'NONSSL') {
  237.                 $link = HTTP_SERVER;
  238.             } elseif ($connection == 'SSL') {
  239.                 if (ENABLE_SSL == 'true') {
  240.                     $link = HTTPS_SERVER ;
  241.                 } else {
  242.                     $link = HTTP_SERVER;
  243.                 }
  244.             } else {
  245.                 die('</td></tr></table></td></tr></table><br /><br /><strong class="note">Error!<br /><br />Unable to determine connection method on a link!<br /><br />Known methods: NONSSL SSL</strong><br /><br />');
  246.             }
  247.  
  248.     if ($use_dir_ws_catalog) {
  249.       if ($connection == 'SSL') {
  250.         $link .= DIR_WS_HTTPS_CATALOG;
  251.       } else {
  252.         $link .= DIR_WS_CATALOG;
  253.       }
  254.     }
  255.  
  256.             if (!$static) {
  257.                 if ($this->not_null($parameters)) {
  258.                     $link .= 'index.php?main_page='. $page . "&" . $this->output_string($parameters);
  259.                 } else {
  260.                     $link .= 'index.php?main_page=' . $page;
  261.                 }
  262.             } else {
  263.                 if ($this->not_null($parameters)) {
  264.                     $link .= $page . "?" . $this->output_string($parameters);
  265.                 } else {
  266.                     $link .= $page;
  267.                 }
  268.             }
  269.  
  270.             $separator = '&';
  271.  
  272.             while ( (substr($link, -1) == '&') || (substr($link, -1) == '?') ) $link = substr($link, 0, -1);
  273.  
  274.             if ( ($add_session_id == true) && ($session_started == true) && (SESSION_FORCE_COOKIE_USE == 'False') ) {
  275.                 if ($this->not_null($this->attributes['SID'])) {
  276.                     $_sid = $this->attributes['SID'];
  277.                 } elseif ( ( ($request_type == 'NONSSL') && ($connection == 'SSL') && (ENABLE_SSL == 'true') ) || ( ($request_type == 'SSL') && ($connection == 'NONSSL') ) ) {
  278.                     if ($http_domain != $https_domain) {
  279.                         $_sid = session_name() . '=' . session_id();
  280.                     }
  281.                 }
  282.             }
  283.  
  284.             // clean up the link before processing
  285.             while (strstr($link, '&&')) $link = str_replace('&&', '&', $link);
  286.             while (strstr($link, '&amp;&amp;')) $link = str_replace('&amp;&amp;', '&amp;', $link);
  287.  
  288.             switch(true){
  289.                 case (!isset($_SESSION['customer_id']) && defined('ENABLE_PAGE_CACHE') && ENABLE_PAGE_CACHE == 'true' && class_exists('page_cache')):
  290.                     $page_cache = true;
  291.                     $return = $link . $separator . '<zensid>';
  292.                     break;
  293.                 case (isset($_sid)):
  294.                     $page_cache = false;
  295.                     $return = $link . $separator . $_sid;
  296.                     break;
  297.                 default:
  298.                     $page_cache = false;
  299.                     $return = $link;
  300.                     break;
  301.             }
  302.  
  303.             $this->cache['STANDARD_URLS'][] = $link;
  304.  
  305.             switch(true){
  306.                 case ($this->attributes['SEO_URLS_USE_W3C_VALID'] == 'true' && !$page_cache):
  307.                     return htmlspecialchars(utf8_encode($return));
  308.                     break;
  309.                 default:
  310.                     return $return;
  311.                     break;
  312.             }# end swtich
  313.         } # end default tep_href function
  314.  
  315.         function add_sid($link, $add_session_id, $connection, $separator) {
  316.             global $request_type, $http_domain, $https_domain;
  317.  
  318.             if ( ($add_session_id == true) && ($this->attributes['SESSION_STARTED']) && (SESSION_FORCE_COOKIE_USE == 'False') ) {
  319.                 if ($this->not_null($this->attributes['SID'])) {
  320.                     $_sid = $this->attributes['SID'];
  321.                 } elseif ( ( ($request_type == 'NONSSL') && ($connection == 'SSL') && (ENABLE_SSL == 'true') ) || ( ($request_type == 'SSL') && ($connection == 'NONSSL') ) ) {
  322.                     if ($http_domain != $https_domain) {
  323.                         $_sid = session_name() . '=' . session_id();
  324.                     }
  325.                 }
  326.             }
  327.  
  328.             switch(true){
  329.                 case (!isset($_SESSION['customer_id']) && defined('ENABLE_PAGE_CACHE') && ENABLE_PAGE_CACHE == 'true' && class_exists('page_cache')):
  330.                     $return = $link . $separator . '<zensid>';
  331.                     break;
  332.                 case ($this->not_null($_sid)):
  333.                     $return = $link . $separator . $_sid;
  334.                     break;
  335.                 default:
  336.                     $return = $link;
  337.                     break;
  338.             } # end switch
  339.             return $return;
  340.         } # end function
  341.  
  342. /**
  343.  * Function to parse the parameters into an SEO URL
  344.  * @author Bobby Easland
  345.  * @version 1.2
  346.  * @param string $page
  347.  * @param string $params
  348.  * @param string $separator NOTE: passed by reference
  349.  * @return string
  350.  */
  351.     function parse_parameters($page, $params, &$separator) {
  352.         $p = @explode('&', $params);
  353.         krsort($p);
  354.         $container = array();
  355.         foreach ($p as $index => $valuepair){
  356.             $p2 = @explode('=', $valuepair);
  357.             switch ($p2[0]){
  358.  
  359.                 case 'article_id':
  360.                     switch(true) {
  361.                         case ($page == FILENAME_NEWS_ARTICLE):
  362.                             $url = $this->make_url($page, 'news/' . $this->get_news_article_name($p2[1]), 'news_article_id', $p2[1], '.html', $separator);
  363.                             break;
  364.                         case ($page == FILENAME_NEWS_COMMENTS):
  365.                             $url = $this->make_url($page, 'news/' . $this->get_news_article_name($p2[1]), 'news_comments_article_id', $p2[1], '-comments.html', $separator);
  366.                             break;
  367.                         default:
  368.                             $container[$p2[0]] = $p2[1];
  369.                             break;
  370.                     }
  371.                     break;
  372.  
  373.                 case 'date':
  374.                     switch(true) {
  375.                         case ($page == FILENAME_NEWS_ARCHIVE):
  376.                             $url = $this->make_url($page, FILENAME_NEWS_INDEX, 'news_archive_dates', $p2[1], '.html', $separator);
  377.                             break;
  378.                         case ($page == FILENAME_NEWS_INDEX):
  379.                             $url = $this->make_url($page, FILENAME_NEWS_INDEX, 'news_dates', $p2[1], '.html', $separator);
  380.                             break;
  381.                         default:
  382.                             $container[$p2[0]] = $p2[1];
  383.                             break;
  384.                     }
  385.                     break;
  386.  
  387.                 case 'pages_id':
  388.                     switch(true) {
  389.                         case ($page == FILENAME_INFO_MANAGER):
  390.                             $url = $this->make_url($page, $this->get_info_manager_page_name($p2[1]), 'info_manager_page_id', $p2[1], '.html', $separator);
  391.                             break;
  392.                         default:
  393.                             $container[$p2[0]] = $p2[1];
  394.                             break;
  395.                     }
  396.                     break;
  397.  
  398.                 case 'products_id':
  399.                     switch(true) {
  400. //                      case ($page == FILENAME_PRODUCT_INFO && !$this->is_attribute_string($params)):
  401.                         case ($page == FILENAME_PRODUCT_INFO):
  402.                             $url = $this->make_url($page, $this->get_product_name($p2[1]), $p2[0], $p2[1], '.html', $separator);
  403.                             break;
  404.                         case ($page == FILENAME_PRODUCT_REVIEWS):
  405.                             $url = $this->make_url($page, $this->get_product_name($p2[1]), 'products_id_review', $p2[1], '.html', $separator);
  406.                             break;
  407.                         case ($page == FILENAME_PRODUCT_REVIEWS_INFO):
  408.                             $url = $this->make_url($page, $this->get_product_name($p2[1]), 'products_id_review_info', $p2[1], '.html', $separator);
  409.                             break;
  410.                         default:
  411.                             $container[$p2[0]] = $p2[1];
  412.                             break;
  413.                     } # end switch
  414.                     break;
  415.                 case 'cPath':
  416.                     switch(true){
  417.                         case ($page == FILENAME_DEFAULT):
  418.                             $url = $this->make_url($page, $this->get_category_name($p2[1]), $p2[0], $p2[1], '.html', $separator);
  419.                             break;
  420.                         case ($this->is_product_string($params)):
  421.                             if ($this->attributes['SEO_ADD_CPATH_TO_PRODUCT_URLS'] == 'true') {
  422.                                 $container[$p2[0]] = $p2[1];
  423.                             }
  424.                             break;
  425.                         default:
  426.                             $container[$p2[0]] = $p2[1];
  427.                             break;
  428.                         } # end switch
  429.                     break;
  430.                 case 'manufacturers_id':
  431.                     switch(true){
  432.                         case ($page == FILENAME_DEFAULT && !$this->is_cPath_string($params) && !$this->is_product_string($params)):
  433.                             $url = $this->make_url($page, $this->get_manufacturer_name($p2[1]), $p2[0], $p2[1], '.html', $separator);
  434.                             break;
  435.                         case ($page == FILENAME_PRODUCT_INFO):
  436.                             break;
  437.                         default:
  438.                             $container[$p2[0]] = $p2[1];
  439.                             break;
  440.                         } # end switch
  441.                     break;
  442.                 case 'pID':
  443.                     switch(true){
  444.                         case ($page == FILENAME_POPUP_IMAGE):
  445.                         $url = $this->make_url($page, $this->get_product_name($p2[1]), $p2[0], $p2[1], '.html', $separator);
  446.                         break;
  447.                     default:
  448.                         $container[$p2[0]] = $p2[1];
  449.                         break;
  450.                     } # end switch
  451.                     break;
  452.                 case 'id':  // EZ-Pages
  453.                     switch(true){
  454.                         case ($page == FILENAME_EZPAGES):
  455.                             $url = $this->make_url($page, $this->get_ezpages_name($p2[1]), $p2[0], $p2[1], '.html', $separator);
  456.                             break;
  457.                         default:
  458.                             $container[$p2[0]] = $p2[1];
  459.                             break;
  460.                         } # end switch
  461.                     break;
  462.                 default:
  463.                     $container[$p2[0]] = $p2[1];
  464.                     break;
  465.             } # end switch
  466.         } # end foreach $p
  467.         $url = isset($url) ? $url : $page;
  468.         if ( sizeof($container) > 0 ){
  469.             if ( $imploded_params = $this->implode_assoc($container) ){
  470.                 $url .= $separator . $this->output_string( $imploded_params );
  471.                 $separator = '&';
  472.             }
  473.         }
  474.         return $url;
  475.     } # end function
  476.  
  477. /**
  478.  * Function to return the generated SEO URL
  479.  * @author Bobby Easland
  480.  * @version 1.0
  481.  * @param string $page
  482.  * @param string $string Stripped, formed anchor
  483.  * @param string $anchor_type Parameter type (products_id, cPath, etc.)
  484.  * @param integer $id
  485.  * @param string $extension Default = .html
  486.  * @param string $separator NOTE: passed by reference
  487.  * @return string
  488.  */
  489.     function make_url($page, $string, $anchor_type, $id, $extension = '.html', &$separator){
  490.         // Right now there is but one rewrite method since cName was dropped
  491.         // In the future there will be additional methods here in the switch
  492.         switch ( $this->attributes['SEO_REWRITE_TYPE'] ){
  493.             case 'Rewrite':
  494.                 return $string . $this->reg_anchors[$anchor_type] . $id . $extension;
  495.                 break;
  496.             default:
  497.                 break;
  498.         } # end switch
  499.     } # end function
  500.  
  501.     function get_info_manager_page_name($pages_id) {
  502.         switch(true){
  503.             case ($this->attributes['USE_SEO_CACHE_GLOBAL'] == 'true' && defined('INFO_MANAGER_PAGE_NAME_' . $pages_id)):
  504.                 $return = constant('INFO_MANAGER_PAGE_NAME_' . $pages_id);
  505.                 $this->cache['INFO_MANAGER_PAGES'][$pages_id] = $return;
  506.                 break;
  507.  
  508.             case ($this->attributes['USE_SEO_CACHE_GLOBAL'] == 'true' && isset($this->cache['INFO_MANAGER_PAGES'][$pages_id])):
  509.                 $return = $this->cache['INFO_MANAGER_PAGES'][$pages_id];
  510.                 break;
  511.  
  512.             default:
  513.                 $sql = "SELECT pages_title
  514.                         FROM " . TABLE_INFO_MANAGER . "
  515.                         WHERE pages_id = " . (int)$pages_id . "
  516.                         LIMIT 1";
  517.                 $result = $this->db->Execute($sql);
  518.                 $pages_title = $this->strip($result->fields['pages_title']);
  519.                 $this->cache['INFO_MANAGER_PAGES'][$pages_id] = $pages_title;
  520.                 $return = $pages_title;
  521.                 break;
  522.         }
  523.         return $return;
  524.     }
  525.  
  526.     function get_news_article_name($article_id) {
  527.         switch(true){
  528.             case ($this->attributes['USE_SEO_CACHE_GLOBAL'] == 'true' && defined('NEWS_ARTICLE_NAME_' . $article_id)):
  529.                 $return = constant('NEWS_ARTICLE_NAME_' . $article_id);
  530.                 $this->cache['NEWS_ARTICLES'][$article_id] = $return;
  531.                 break;
  532.  
  533.             case ($this->attributes['USE_SEO_CACHE_GLOBAL'] == 'true' && isset($this->cache['NEWS_ARTICLES'][$article_id])):
  534.                 $return = $this->cache['NEWS_ARTICLES'][$article_id];
  535.                 break;
  536.  
  537.             default:
  538.                 $sql = "SELECT news_article_name
  539.                         FROM " . TABLE_NEWS_ARTICLES_TEXT . "
  540.                         WHERE article_id = " . (int)$article_id . "
  541.                         AND language_id = " . (int)$this->languages_id . "
  542.                         LIMIT 1";
  543.                 $result = $this->db->Execute($sql);
  544.                 $news_article_name = $this->strip($result->fields['news_article_name']);
  545.                 $this->cache['NEWS_ARTICLES'][$article_id] = $news_article_name;
  546.                 $return = $news_article_name;
  547.                 break;
  548.         }
  549.         return $return;
  550.     }
  551.  
  552. /**
  553.  * Function to get the product name. Use evaluated cache, per page cache, or database query in that order of precedent
  554.  * @author Bobby Easland
  555.  * @version 1.1
  556.  * @param integer $pID
  557.  * @return string Stripped anchor text
  558.  */
  559.     function get_product_name($pID){
  560.         switch(true){
  561.             case ($this->attributes['USE_SEO_CACHE_GLOBAL'] == 'true' && defined('PRODUCT_NAME_' . $pID)):
  562.                 $return = constant('PRODUCT_NAME_' . $pID);
  563.                 $this->cache['PRODUCTS'][$pID] = $return;
  564.                 break;
  565.  
  566.             case ($this->attributes['USE_SEO_CACHE_GLOBAL'] == 'true' && isset($this->cache['PRODUCTS'][$pID])):
  567.                 $return = $this->cache['PRODUCTS'][$pID];
  568.                 break;
  569.  
  570.             default:
  571.                 $sql = "SELECT products_name as pName
  572.                         FROM " . TABLE_PRODUCTS_DESCRIPTION . "
  573.                         WHERE products_id = " . (int)$pID . "
  574.                         AND language_id = " . (int)$this->languages_id . "
  575.                         LIMIT 1";
  576.                 $result = $this->db->Execute($sql);
  577.                 $pName = $this->strip($result->fields['pName']);
  578.                 $this->cache['PRODUCTS'][$pID] = $pName;
  579.                 $return = $pName;
  580.                 break;
  581.         } # end switch
  582.         return $return;
  583.     } # end function
  584.  
  585. /**
  586.  * Function to get the category name. Use evaluated cache, per page cache, or database query in that order of precedent
  587.  * @author Bobby Easland
  588.  * @version 1.1
  589.  * @param integer $cID NOTE: passed by reference
  590.  * @return string Stripped anchor text
  591.  */
  592.     function get_category_name(&$cID){
  593.         $full_cPath = $this->get_full_cPath($cID, $single_cID); // full cPath needed for uniformity
  594.         switch(true){
  595.             case ($this->attributes['USE_SEO_CACHE_GLOBAL'] == 'true' && defined('CATEGORY_NAME_' . $full_cPath)):
  596.                 $return = constant('CATEGORY_NAME_' . $full_cPath);
  597.                 $this->cache['CATEGORIES'][$full_cPath] = $return;
  598.                 break;
  599.             case ($this->attributes['USE_SEO_CACHE_GLOBAL'] == 'true' && isset($this->cache['CATEGORIES'][$full_cPath])):
  600.                 $return = $this->cache['CATEGORIES'][$full_cPath];
  601.                 break;
  602.             default:
  603.                 switch(true){
  604.                     case ($this->attributes['SEO_ADD_CAT_PARENT'] == 'true'):
  605.                         $sql = "SELECT c.categories_id, c.parent_id, cd.categories_name as cName, cd2.categories_name as pName
  606.                                 FROM ".TABLE_CATEGORIES_DESCRIPTION." cd, ".TABLE_CATEGORIES." c
  607.                                 LEFT JOIN ".TABLE_CATEGORIES_DESCRIPTION." cd2
  608.                                 ON c.parent_id=cd2.categories_id AND cd2.language_id='".(int)$this->languages_id."'
  609.                                 WHERE c.categories_id='".(int)$single_cID."'
  610.                                 AND cd.categories_id='".(int)$single_cID."'
  611.                                 AND cd.language_id='".(int)$this->languages_id."'
  612.                                 LIMIT 1";
  613.                         $result = $this->db->Execute($sql);
  614.                         $cName = $this->not_null($result->fields['pName']) ? $result->fields['pName'] . ' ' . $result->fields['cName'] : $result->fields['cName'];
  615.                         break;
  616.                     default:
  617.                         $sql = "SELECT categories_name as cName
  618.                                 FROM ".TABLE_CATEGORIES_DESCRIPTION."
  619.                                 WHERE categories_id='".(int)$single_cID."'
  620.                                 AND language_id='".(int)$this->languages_id."'
  621.                                 LIMIT 1";
  622.                         $result = $this->db->Execute($sql);
  623.                         $cName = $result->fields['cName'];
  624.                         break;
  625.                 }
  626.                 $cName = $this->strip($cName);
  627.                 $this->cache['CATEGORIES'][$full_cPath] = $cName;
  628.                 $return = $cName;
  629.                 break;
  630.         } # end switch
  631.         $cID = $full_cPath;
  632.         return $return;
  633.     } # end function
  634.  
  635. /**
  636.  * Function to get the manufacturer name. Use evaluated cache, per page cache, or database query in that order of precedent.
  637.  * @author Bobby Easland
  638.  * @version 1.1
  639.  * @param integer $mID
  640.  * @return string
  641.  */
  642.     function get_manufacturer_name($mID){
  643.         switch(true){
  644.             case ($this->attributes['USE_SEO_CACHE_GLOBAL'] == 'true' && defined('MANUFACTURER_NAME_' . $mID)):
  645.                 $return = constant('MANUFACTURER_NAME_' . $mID);
  646.                 $this->cache['MANUFACTURERS'][$mID] = $return;
  647.                 break;
  648.             case ($this->attributes['USE_SEO_CACHE_GLOBAL'] == 'true' && isset($this->cache['MANUFACTURERS'][$mID])):
  649.                 $return = $this->cache['MANUFACTURERS'][$mID];
  650.                 break;
  651.             default:
  652.                 $sql = "SELECT manufacturers_name as mName
  653.                         FROM ".TABLE_MANUFACTURERS."
  654.                         WHERE manufacturers_id='".(int)$mID."'
  655.                         LIMIT 1";
  656.                 $result = $this->db->Execute($sql);
  657.                 $mName = $this->strip($result->fields['mName']);
  658.                 $this->cache['MANUFACTURERS'][$mID] = $mName;
  659.                 $return = $mName;
  660.                 break;
  661.         } # end switch
  662.         return $return;
  663.     } # end function
  664.  
  665. /**
  666.  * Function to get the EZ-Pages name. Use evaluated cache, per page cache, or database query in that order of precedent.
  667.  * @author Bobby Easland, Ronald Crawford
  668.  * @version 1.0
  669.  * @param integer $mID
  670.  * @return string
  671.  */
  672.     function get_ezpages_name($ezpID){
  673.         switch(true){
  674.             case ($this->attributes['USE_SEO_CACHE_GLOBAL'] == 'true' && defined('EZPAGES_NAME_' . $ezpID)):
  675.                 $return = constant('EZPAGES_NAME_' . $ezpID);
  676.                 $this->cache['EZPAGES'][$ezpID] = $return;
  677.                 break;
  678.             case ($this->attributes['USE_SEO_CACHE_GLOBAL'] == 'true' && isset($this->cache['EZPAGES'][$ezpID])):
  679.                 $return = $this->cache['EZPAGES'][$ezpID];
  680.                 break;
  681.             default:
  682.                 $sql = "SELECT pages_title as ezpName
  683.                         FROM ".TABLE_EZPAGES."
  684.                         WHERE pages_id='".(int)$ezpID."'
  685.                         LIMIT 1";
  686.                 $result = $this->db->Execute($sql);
  687.                 $ezpName = $this->strip($result->fields['ezpName']);
  688.                 $this->cache['EZPAGES'][$ezpID] = $ezpName;
  689.                 $return = $ezpName;
  690.                 break;
  691.         } # end switch
  692.         return $return;
  693.     } # end function
  694.  
  695. /**
  696.  * Function to retrieve full cPath from category ID
  697.  * @author Bobby Easland
  698.  * @version 1.1
  699.  * @param mixed $cID Could contain cPath or single category_id
  700.  * @param integer $original Single category_id passed back by reference
  701.  * @return string Full cPath string
  702.  */
  703.     function get_full_cPath($cID, &$original){
  704.         if ( is_numeric(strpos($cID, '_')) ){
  705.             $temp = @explode('_', $cID);
  706.             $original = $temp[sizeof($temp)-1];
  707.             return $cID;
  708.         } else {
  709.             $c = array();
  710.             $this->GetParentCategories($c, $cID);
  711.             $c = array_reverse($c);
  712.             $c[] = $cID;
  713.             $original = $cID;
  714.             $cID = sizeof($c) > 1 ? implode('_', $c) : $cID;
  715.             return $cID;
  716.         }
  717.     } # end function
  718.  
  719. /**
  720.  * Recursion function to retrieve parent categories from category ID
  721.  * @author Bobby Easland
  722.  * @version 1.0
  723.  * @param mixed $categories Passed by reference
  724.  * @param integer $categories_id
  725.  */
  726.     function GetParentCategories(&$categories, $categories_id) {
  727.         $sql = "SELECT parent_id FROM " . TABLE_CATEGORIES . " WHERE categories_id = " . (int)$categories_id;
  728.  
  729.         $parent_categories = $this->db->Execute($sql);
  730.  
  731.         while (!$parent_categories->EOF) {
  732.             if ($parent_categories->fields['parent_id'] == 0) return true;
  733.  
  734.             $categories[sizeof($categories)] = $parent_categories->fields['parent_id'];
  735.  
  736.             if ($parent_categories->fields['parent_id'] != $categories_id) {
  737.                 $this->GetParentCategories($categories, $parent_categories->fields['parent_id']);
  738.             }
  739.  
  740.             $parent_categories->MoveNext();
  741.         }
  742.     }
  743.  
  744.     function not_null($value) {
  745.         return zen_not_null($value);
  746.     }
  747.  
  748.     function is_attribute_string($params){
  749.         if (preg_match('/products_id=([0-9]+):([a-zA-z0-9]{32})/', $params)) {
  750.             return true;
  751.         }
  752.  
  753.         return false;
  754.     }
  755.  
  756.     function is_product_string($params) {
  757.         if (preg_match('/products_id=/i', $params)) {
  758.             return true;
  759.         }
  760.  
  761.         return false;
  762.     }
  763.  
  764.     function is_cPath_string($params) {
  765.         if (preg_match('/cPath=/i', $params)) {
  766.             return true;
  767.         }
  768.  
  769.         return false;
  770.     }
  771.  
  772. /**
  773.  * Function to strip the string of punctuation and white space
  774.  * @author Bobby Easland
  775.  * @version 1.1
  776.  * @param string $string
  777.  * @return string Stripped text. Removes all non-alphanumeric characters.
  778.  */
  779.     function strip($string){
  780.         if ( is_array($this->attributes['SEO_CHAR_CONVERT_SET']) ) $string = strtr($string, $this->attributes['SEO_CHAR_CONVERT_SET']);
  781.         $pattern = $this->attributes['SEO_REMOVE_ALL_SPEC_CHARS'] == 'true'
  782.                         ?   "([^[:alnum:]])+"
  783.                         :   "([[:punct:]])+";
  784.         $anchor = ereg_replace($pattern, '', strtolower($string));
  785.         $pattern = "([[:space:]]|[[:blank:]])+";
  786.         $anchor = ereg_replace($pattern, '-', $anchor);
  787.         return $this->short_name($anchor); // return the short filtered name
  788.     } # end function
  789.  
  790. /**
  791.  * Function to expand the SEO_CONVERT_SET group
  792.  * @author Bobby Easland
  793.  * @version 1.0
  794.  * @param string $set
  795.  * @return mixed
  796.  */
  797.     function expand($set){
  798.         if ( $this->not_null($set) ){
  799.             if ( $data = @explode(',', $set) ){
  800.                 foreach ( $data as $index => $valuepair){
  801.                     $p = @explode('=>', $valuepair);
  802.                     $container[trim($p[0])] = trim($p[1]);
  803.                 }
  804.                 return $container;
  805.             } else {
  806.                 return 'false';
  807.             }
  808.         } else {
  809.             return 'false';
  810.         }
  811.     } # end function
  812. /**
  813.  * Function to return the short word filtered string
  814.  * @author Bobby Easland
  815.  * @version 1.0
  816.  * @param string $str
  817.  * @param integer $limit
  818.  * @return string Short word filtered
  819.  */
  820.     function short_name($str, $limit=3){
  821.         if ( $this->attributes['SEO_URLS_FILTER_SHORT_WORDS'] != 'false' ) $limit = (int)$this->attributes['SEO_URLS_FILTER_SHORT_WORDS'];
  822.         $foo = @explode('-', $str);
  823.         foreach($foo as $index => $value){
  824.             switch (true){
  825.                 case ( strlen($value) <= $limit ):
  826.                     continue;
  827.                 default:
  828.                     $container[] = $value;
  829.                     break;
  830.             }
  831.         } # end foreach
  832.         $container = ( sizeof($container) > 1 ? implode('-', $container) : $str );
  833.         return $container;
  834.     }
  835.  
  836. /**
  837.  * Function to implode an associative array
  838.  * @author Bobby Easland
  839.  * @version 1.0
  840.  * @param array $array Associative data array
  841.  * @param string $inner_glue
  842.  * @param string $outer_glue
  843.  * @return string
  844.  */
  845.     function implode_assoc($array, $inner_glue='=', $outer_glue='&') {
  846.         $output = array();
  847.         foreach( $array as $key => $item ){
  848.             if ( $this->not_null($key) && $this->not_null($item) ){
  849.                 $output[] = $key . $inner_glue . $item;
  850.             }
  851.         } # end foreach
  852.         return @implode($outer_glue, $output);
  853.     }
  854.  
  855. /**
  856.  * Function to translate a string
  857.  * @author Bobby Easland
  858.  * @version 1.0
  859.  * @param string $data String to be translated
  860.  * @param array $parse Array of tarnslation variables
  861.  * @return string
  862.  */
  863.     function parse_input_field_data($data, $parse) {
  864.         return strtr(trim($data), $parse);
  865.     }
  866.  
  867. /**
  868.  * Function to output a translated or sanitized string
  869.  * @author Bobby Easland
  870.  * @version 1.0
  871.  * @param string $sting String to be output
  872.  * @param mixed $translate Array of translation characters
  873.  * @param boolean $protected Switch for htemlspecialchars processing
  874.  * @return string
  875.  */
  876.     function output_string($string, $translate = false, $protected = false) {
  877.         if ($protected == true) {
  878.           return htmlspecialchars($string);
  879.         } else {
  880.           if ($translate == false) {
  881.             return $this->parse_input_field_data($string, array('"' => '&quot;'));
  882.           } else {
  883.             return $this->parse_input_field_data($string, $translate);
  884.           }
  885.         }
  886.     }
  887.  
  888. /**
  889.  * Function to generate EZ-Pages cache entries
  890.  * @author Bobby Easland, Ronald Crawford
  891.  * @version 1.0
  892.  */
  893.     function generate_ezpages_cache(){
  894.         $this->is_cached($this->cache_file . 'ezpages', $is_cached, $is_expired);
  895.         if ( !$is_cached || $is_expired ) {
  896.         $sql = "SELECT pages_id as id, pages_title as name
  897.                 FROM ".TABLE_EZPAGES."
  898.                 WHERE language_id = '".(int)$this->languages_id."'";
  899.         $ezpages = $this->db->Execute($sql);
  900.         $ezpages_cache = '';
  901.         while (!$ezpages->EOF) {
  902.             $define = 'define(\'EZPAGES_NAME_' . $ezpages->fields['id'] . '\', \'' . $this->strip($ezpages->fields['name']) . '\');';
  903.             $ezpages_cache .= $define . "\n";
  904.             eval("$define");
  905.             $product->MoveNext();
  906.         }
  907.         $this->save_cache($this->cache_file . 'ezpages', $ezpages_cache, 'EVAL', 1 , 1);
  908.         unset($ezpages_cache);
  909.         } else {
  910.             $this->get_cache($this->cache_file . 'ezpages');
  911.         }
  912.     } # end function
  913.  
  914. /**
  915.  * Function to generate products cache entries
  916.  * @author Bobby Easland
  917.  * @version 1.0
  918.  */
  919.     function generate_products_cache(){
  920.         $this->is_cached($this->cache_file . 'products', $is_cached, $is_expired);
  921.         if ( !$is_cached || $is_expired ) {
  922.         $sql = "SELECT p.products_id as id, pd.products_name as name
  923.                 FROM ".TABLE_PRODUCTS." p
  924.                 LEFT JOIN ".TABLE_PRODUCTS_DESCRIPTION." pd
  925.                 ON p.products_id=pd.products_id
  926.                 AND pd.language_id='".(int)$this->languages_id."'
  927.                 WHERE p.products_status='1'";
  928.         $product = $this->db->Execute($sql);
  929.         $prod_cache = '';
  930.         while (!$product->EOF) {
  931.             $define = 'define(\'PRODUCT_NAME_' . $product->fields['id'] . '\', \'' . $this->strip($product->fields['name']) . '\');';
  932.             $prod_cache .= $define . "\n";
  933.             eval("$define");
  934.             $product->MoveNext();
  935.         }
  936.         $this->save_cache($this->cache_file . 'products', $prod_cache, 'EVAL', 1 , 1);
  937.         unset($prod_cache);
  938.         } else {
  939.             $this->get_cache($this->cache_file . 'products');
  940.         }
  941.     } # end function
  942.  
  943. /**
  944.  * Function to generate manufacturers cache entries
  945.  * @author Bobby Easland
  946.  * @version 1.0
  947.  */
  948.     function generate_manufacturers_cache(){
  949.         $this->is_cached($this->cache_file . 'manufacturers', $is_cached, $is_expired);
  950.         if ( !$is_cached || $is_expired ) { // it's not cached so create it
  951.         $sql = "SELECT m.manufacturers_id as id, m.manufacturers_name as name
  952.                 FROM ".TABLE_MANUFACTURERS." m
  953.                 LEFT JOIN ".TABLE_MANUFACTURERS_INFO." md
  954.                 ON m.manufacturers_id=md.manufacturers_id
  955.                 AND md.languages_id='".(int)$this->languages_id."'";
  956.         $manufacturers = $this->db->Execute($sql);
  957.         $man_cache = '';
  958.         while (!$manufacturers->EOF) {
  959.             $define = 'define(\'MANUFACTURER_NAME_' . $manufacturer->fields['id'] . '\', \'' . $this->strip($manufacturer->fields['name']) . '\');';
  960.             $man_cache .= $define . "\n";
  961.             eval("$define");
  962.             $manufacturers->MoveNext();
  963.         }
  964.         $this->save_cache($this->cache_file . 'manufacturers', $man_cache, 'EVAL', 1 , 1);
  965.         unset($man_cache);
  966.         } else {
  967.             $this->get_cache($this->cache_file . 'manufacturers');
  968.         }
  969.     } # end function
  970.  
  971. /**
  972.  * Function to generate categories cache entries
  973.  * @author Bobby Easland
  974.  * @version 1.1
  975.  */
  976.     function generate_categories_cache(){
  977.         $this->is_cached($this->cache_file . 'categories', $is_cached, $is_expired);
  978.         if ( !$is_cached || $is_expired ) { // it's not cached so create it
  979.             switch(true){
  980.                 case ($this->attributes['SEO_ADD_CAT_PARENT'] == 'true'):
  981.                     $sql = "SELECT c.categories_id as id, c.parent_id, cd.categories_name as cName, cd2.categories_name as pName
  982.                             FROM ".TABLE_CATEGORIES." c
  983.                             LEFT JOIN ".TABLE_CATEGORIES_DESCRIPTION." cd2
  984.                             ON c.parent_id=cd2.categories_id AND cd2.language_id='".(int)$this->languages_id."',
  985.                             ".TABLE_CATEGORIES_DESCRIPTION." cd
  986.                             WHERE c.categories_id=cd.categories_id
  987.                             AND cd.language_id='".(int)$this->languages_id."'";
  988.                     //IMAGINADW.COM;
  989.                     break;
  990.                 default:
  991.                     $sql = "SELECT categories_id as id, categories_name as cName
  992.                             FROM ".TABLE_CATEGORIES_DESCRIPTION."
  993.                             WHERE language_id='".(int)$this->languages_id."'";
  994.                     break;
  995.             } # end switch
  996.         $category = $this->db->Execute($sql);
  997.         $cat_cache = '';
  998.         while (!$category->EOF) {
  999.             $id = $this->get_full_cPath($category->fields['id'], $single_cID);
  1000.             $name = $this->not_null($category->fields['pName']) ? $category->fields['pName'] . ' ' . $category->fields['cName'] : $category->fields['cName'];
  1001.             $define = 'define(\'CATEGORY_NAME_' . $id . '\', \'' . $this->strip($name) . '\');';
  1002.             $cat_cache .= $define . "\n";
  1003.             eval("$define");
  1004.             $category->MoveNext();
  1005.         }
  1006.         $this->save_cache($this->cache_file . 'categories', $cat_cache, 'EVAL', 1 , 1);
  1007.         unset($cat_cache);
  1008.         } else {
  1009.             $this->get_cache($this->cache_file . 'categories');
  1010.         }
  1011.     } # end function
  1012.  
  1013. /**
  1014.  * Function to generate articles cache entries
  1015.  * @author Bobby Easland
  1016.  * @version 1.0
  1017.  */
  1018.     function generate_news_articles_cache(){
  1019.         $this->is_cached($this->cache_file . 'news_articles', $is_cached, $is_expired);
  1020.         if ( !$is_cached || $is_expired ) { // it's not cached so create it
  1021.             $sql = "SELECT article_id as id, news_article_name as name
  1022.                     FROM ".TABLE_NEWS_ARTICLES_TEXT."
  1023.                     WHERE language_id = '".(int)$this->languages_id."'";
  1024.             $article = $this->db->Execute($sql);
  1025.             $article_cache = '';
  1026.             while (!$article->EOF) {
  1027.                 $define = 'define(\'NEWS_ARTICLE_NAME_' . $article->fields['id'] . '\', \'' . $this->strip($article->fields['name']) . '\');';
  1028.                 $article_cache .= $define . "\n";
  1029.                 eval("$define");
  1030.                 $article->MoveNext();
  1031.             }
  1032.             $this->save_cache($this->cache_file . 'news_articles', $article_cache, 'EVAL', 1 , 1);
  1033.             unset($article_cache);
  1034.         } else {
  1035.             $this->get_cache($this->cache_file . 'news_articles');
  1036.         }
  1037.     } # end function
  1038.  
  1039. /**
  1040.  * Function to generate information cache entries
  1041.  * @author Bobby Easland
  1042.  * @version 1.0
  1043.  */
  1044.     function generate_info_manager_cache(){
  1045.         $this->is_cached($this->cache_file . 'info_manager', $is_cached, $is_expired);
  1046.         if ( !$is_cached || $is_expired ) { // it's not cached so create it
  1047.             $sql = "SELECT pages_id as id, pages_title as name
  1048.                     FROM ".TABLE_INFO_MANAGER;
  1049.             $information = $this->db->Execute($sql);
  1050.             $information_cache = '';
  1051.             while (!$information->EOF) {
  1052.                 $define = 'define(\'INFO_MANAGER_PAGE_NAME_' . $information->fields['id'] . '\', \'' . $this->strip($information->fields['name']) . '\');';
  1053.                 $information_cache .= $define . "\n";
  1054.                 eval("$define");
  1055.                 $information->MoveNext();
  1056.             }
  1057.             $this->save_cache($this->cache_file . 'info_manager', $information_cache, 'EVAL', 1 , 1);
  1058.             unset($information_cache);
  1059.         } else {
  1060.             $this->get_cache($this->cache_file . 'info_manager');
  1061.         }
  1062.     } # end function
  1063.  
  1064. /**
  1065.  * Function to save the cache to database
  1066.  * @author Bobby Easland
  1067.  * @version 1.0
  1068.  * @param string $name Cache name
  1069.  * @param mixed $value Can be array, string, PHP code, or just about anything
  1070.  * @param string $method RETURN, ARRAY, EVAL
  1071.  * @param integer $gzip Enables compression
  1072.  * @param integer $global Sets whether cache record is global is scope
  1073.  * @param string $expires Sets the expiration
  1074.  */
  1075.     function save_cache($name, $value, $method='RETURN', $gzip=1, $global=0, $expires = '30 days'){
  1076.         $expires = date('Y-m-d H:i:s', strtotime('+' . $expires));
  1077.  
  1078.         if ($method == 'ARRAY') $value = serialize($value);
  1079.         $value = ( $gzip === 1 ? base64_encode(gzdeflate($value, 1)) : addslashes($value) );
  1080.         $sql_data_array = array(
  1081.             'cache_id' => md5($name),
  1082.             'cache_language_id' => (int)$this->languages_id,
  1083.             'cache_name' => $name,
  1084.             'cache_data' => $value,
  1085.             'cache_global' => (int)$global,
  1086.             'cache_gzip' => (int)$gzip,
  1087.             'cache_method' => $method,
  1088.             'cache_date' => date("Y-m-d H:i:s"),
  1089.             'cache_expires' => $expires
  1090.         );
  1091.         $this->is_cached($name, $is_cached, $is_expired);
  1092.         $cache_check = ( $is_cached ? 'true' : 'false' );
  1093.         switch ( $cache_check ) {
  1094.             case 'true':
  1095.                 zen_db_perform(TABLE_SEO_CACHE, $sql_data_array, 'update', "cache_id='".md5($name)."'");
  1096.                 break;
  1097.             case 'false':
  1098.                 zen_db_perform(TABLE_SEO_CACHE, $sql_data_array, 'insert');
  1099.                 break;
  1100.             default:
  1101.                 break;
  1102.         } # end switch ($cache check)
  1103.         # unset the variables...clean as we go
  1104.         unset($value, $expires, $sql_data_array);
  1105.     }# end function save_cache()
  1106.  
  1107. /**
  1108.  * Function to get cache entry
  1109.  * @author Bobby Easland
  1110.  * @version 1.0
  1111.  * @param string $name
  1112.  * @param boolean $local_memory
  1113.  * @return mixed
  1114.  */
  1115.     function get_cache($name = 'GLOBAL', $local_memory = false){
  1116.         $select_list = 'cache_id, cache_language_id, cache_name, cache_data, cache_global, cache_gzip, cache_method, cache_date, cache_expires';
  1117.         $global = ( $name == 'GLOBAL' ? true : false ); // was GLOBAL passed or is using the default?
  1118.         switch($name){
  1119.             case 'GLOBAL':
  1120.                 $cache = $this->db->Execute("SELECT ".$select_list." FROM " . TABLE_SEO_CACHE . " WHERE cache_language_id='".(int)$this->languages_id."' AND cache_global='1'");
  1121.                 break;
  1122.             default:
  1123.                 $cache = $this->db->Execute("SELECT ".$select_list." FROM " . TABLE_SEO_CACHE . " WHERE cache_id='".md5($name)."' AND cache_language_id='".(int)$this->languages_id."'");
  1124.                 break;
  1125.         }
  1126.         $num_rows = $cache->RecordCount();
  1127.         if ($num_rows){
  1128.             $container = array();
  1129.             while(!$cache->EOF){
  1130.                 $cache_name = $cache->fields['cache_name'];
  1131.                 if ( $cache->fields['cache_expires'] > date("Y-m-d H:i:s") ) {
  1132.                     $cache_data = ( $cache->fields['cache_gzip'] == 1 ? gzinflate(base64_decode($cache->fields['cache_data'])) : stripslashes($cache->fields['cache_data']) );
  1133.                     switch($cache->fields['cache_method']){
  1134.                         case 'EVAL': // must be PHP code
  1135.                             eval("$cache_data");
  1136.                             break;
  1137.                         case 'ARRAY':
  1138.                             $cache_data = unserialize($cache_data);
  1139.                         case 'RETURN':
  1140.                         default:
  1141.                             break;
  1142.                     } # end switch ($cache['cache_method'])
  1143.                     if ($global) $container['GLOBAL'][$cache_name] = $cache_data;
  1144.                     else $container[$cache_name] = $cache_data; // not global
  1145.                 } else { // cache is expired
  1146.                     if ($global) $container['GLOBAL'][$cache_name] = false;
  1147.                     else $container[$cache_name] = false;
  1148.                 }# end if ( $cache['cache_expires'] > date("Y-m-d H:i:s") )
  1149.                 if ( $this->keep_in_memory || $local_memory ) {
  1150.                     if ($global) $this->data['GLOBAL'][$cache_name] = $container['GLOBAL'][$cache_name];
  1151.                     else $this->data[$cache_name] = $container[$cache_name];
  1152.                 }
  1153.                 $cache->MoveNext();
  1154.             } # end while ($cache = $this->DB->FetchArray($this->cache_query))
  1155.             unset($cache_data);
  1156.             switch (true) {
  1157.                 case ($num_rows == 1):
  1158.                     if ($global){
  1159.                         if ($container['GLOBAL'][$cache_name] == false || !isset($container['GLOBAL'][$cache_name])) return false;
  1160.                         else return $container['GLOBAL'][$cache_name];
  1161.                     } else { // not global
  1162.                         if ($container[$cache_name] == false || !isset($container[$cache_name])) return false;
  1163.                         else return $container[$cache_name];
  1164.                     } # end if ($global)
  1165.                 case ($num_rows > 1):
  1166.                 default:
  1167.                     return $container;
  1168.                     break;
  1169.             }# end switch (true)
  1170.         } else {
  1171.             return false;
  1172.         }# end if ( $num_rows )
  1173.     } # end function get_cache()
  1174.  
  1175. /**
  1176.  * Function to get cache from memory
  1177.  * @author Bobby Easland
  1178.  * @version 1.0
  1179.  * @param string $name
  1180.  * @param string $method
  1181.  * @return mixed
  1182.  */
  1183.     function get_cache_memory($name, $method = 'RETURN'){
  1184.         $data = ( isset($this->data['GLOBAL'][$name]) ? $this->data['GLOBAL'][$name] : $this->data[$name] );
  1185.         if ( isset($data) && !empty($data) && $data != false ){
  1186.             switch($method){
  1187.                 case 'EVAL': // data must be PHP
  1188.                     eval("$data");
  1189.                     return true;
  1190.                     break;
  1191.                 case 'ARRAY':
  1192.                 case 'RETURN':
  1193.                 default:
  1194.                     return $data;
  1195.                     break;
  1196.             } # end switch ($method)
  1197.         } else {
  1198.             return false;
  1199.         } # end if (isset($data) && !empty($data) && $data != false)
  1200.     } # end function get_cache_memory()
  1201.  
  1202. /**
  1203.  * Function to perform basic garbage collection for database cache system
  1204.  * @author Bobby Easland
  1205.  * @version 1.0
  1206.  */
  1207.     function cache_gc(){
  1208.         $this->db->Execute("DELETE FROM " . TABLE_SEO_CACHE . " WHERE cache_expires <= '" . date("Y-m-d H:i:s") . "'");
  1209.     }
  1210.  
  1211. /**
  1212.  * Function to check if the cache is in the database and expired
  1213.  * @author Bobby Easland
  1214.  * @version 1.0
  1215.  * @param string $name
  1216.  * @param boolean $is_cached NOTE: passed by reference
  1217.  * @param boolean $is_expired NOTE: passed by reference
  1218.  */
  1219.     function is_cached($name, &$is_cached, &$is_expired){ // NOTE: $is_cached and $is_expired is passed by reference !!
  1220.         $this->cache_query = $this->db->Execute("SELECT cache_expires FROM " . TABLE_SEO_CACHE . " WHERE cache_id='".md5($name)."' AND cache_language_id='".(int)$this->languages_id."' LIMIT 1");
  1221.         $is_cached = ( $this->cache_query->RecordCount() > 0 ? true : false );
  1222.         if ($is_cached){
  1223.             $is_expired = ( $this->cache_query->fields['cache_expires'] <= date("Y-m-d H:i:s") ? true : false );
  1224.             unset($check);
  1225.         }
  1226.     }# end function is_cached()
  1227.  
  1228. /**
  1229.  * Function to initialize the redirect logic
  1230.  * @author Bobby Easland
  1231.  * @version 1.1
  1232.  */
  1233.     function check_redirect(){
  1234.         $this->need_redirect = false;
  1235.         $this->uri = ltrim( basename($_SERVER['REQUEST_URI']), '/' );
  1236.         $this->real_uri = ltrim( basename($_SERVER['SCRIPT_NAME']) . '?' . $_SERVER['QUERY_STRING'], '/' );
  1237.  
  1238.         // damn zen cart attributes use illegal url characters
  1239.         if ($this->is_attribute_string($this->uri)) {
  1240.             $parsed_url = parse_url($this->uri);
  1241.             $this->uri_parsed = parse_url($parsed_url['scheme']);
  1242.             $this->uri_parsed['query'] = preg_replace('/products_id=([0-9]+)/', 'products_id=$1:' . $parsed_url['path'], $this->uri_parsed['query']);
  1243.         } else {
  1244.             $this->uri_parsed = parse_url($this->uri);
  1245.         }
  1246.  
  1247.         $this->attributes['SEO_REDIRECT']['URI'] = $this->uri;
  1248.         $this->attributes['SEO_REDIRECT']['REAL_URI'] = $this->real_uri;
  1249.         $this->attributes['SEO_REDIRECT']['URI_PARSED'] = $this->uri_parsed;
  1250.         $this->need_redirect();
  1251.         $this->check_seo_page();
  1252.  
  1253.         if ($this->need_redirect && $this->is_seopage && $this->attributes['USE_SEO_REDIRECT'] == 'true') {
  1254.             $this->do_redirect();
  1255.         }
  1256.     } # end function
  1257.  
  1258. /**
  1259.  * Function to check if the URL needs to be redirected
  1260.  * @author Bobby Easland
  1261.  * @version 1.2
  1262.  */
  1263.     function need_redirect() {
  1264.         $this->need_redirect = ((preg_match('/main_page=/i', $this->uri)) ? true : false);
  1265.         // QUICK AND DIRTY WAY TO DISABLE REDIRECTS ON PAGES WHEN SEO_URLS_ONLY_IN is enabled IMAGINADW.COM
  1266.         $sefu = explode(",", ereg_replace( ' +', '', SEO_URLS_ONLY_IN ));
  1267.         if ((SEO_URLS_ONLY_IN!="") && !in_array($_GET['main_page'],$sefu) ) $this->need_redirect = false;
  1268.         // IMAGINADW.COM
  1269.  
  1270.         $this->attributes['SEO_REDIRECT']['NEED_REDIRECT'] = $this->need_redirect ? 'true' : 'false';
  1271.     }
  1272.  
  1273. /**
  1274.  * Function to check if it's a valid redirect page
  1275.  * @author Bobby Easland
  1276.  * @version 1.1
  1277.  */
  1278.     function check_seo_page() {
  1279.         if (!isset($_GET['main_page']) || (!$this->not_null($_GET['main_page']))) {
  1280.             $_GET['main_page'] = 'index';
  1281.         }
  1282.  
  1283.         $this->is_seopage = (($this->attributes['SEO_ENABLED'] == 'true') ? true : false);
  1284.  
  1285.         $this->attributes['SEO_REDIRECT']['IS_SEOPAGE'] = $this->is_seopage ? 'true' : 'false';
  1286.     }
  1287.  
  1288. /**
  1289.  * Function to perform redirect
  1290.  * @author Bobby Easland
  1291.  * @version 1.0
  1292.  */
  1293.     function do_redirect() {
  1294.         $p = @explode('&', $this->uri_parsed['query']);
  1295.         foreach( $p as $index => $value ) {
  1296.             $tmp = @explode('=', $value);
  1297.  
  1298.             if ($tmp[0] == 'main_page') continue;
  1299.  
  1300.             switch($tmp[0]){
  1301.                 case 'products_id':
  1302.                     if ($this->is_attribute_string('products_id=' . $tmp[1])) {
  1303.                         $pieces = explode(':', $tmp[1]);
  1304.                         $params[] = $tmp[0] . '=' . $pieces[0];
  1305.                     } else {
  1306.                         $params[] = $tmp[0] . '=' . $tmp[1];
  1307.                     }
  1308.                     break;
  1309.                 default:
  1310.                     $params[] = $tmp[0].'='.$tmp[1];
  1311.                     break;
  1312.             }
  1313.         } # end foreach( $params as $var => $value )
  1314.         $params = ( sizeof($params) > 1 ? implode('&', $params) : $params[0] );
  1315.  
  1316.         $url = $this->href_link($_GET['main_page'], $params, 'NONSSL', false);
  1317.         // cleanup url for redirection
  1318.         $url = str_replace('&amp;', '&', $url);
  1319.  
  1320.         switch($this->attributes['USE_SEO_REDIRECT']){
  1321.             case 'true':
  1322.                 header("HTTP/1.1 301 Moved Permanently");
  1323.                 header("Location: $url");
  1324.                 break;
  1325.             default:
  1326.                 $this->attributes['SEO_REDIRECT']['REDIRECT_URL'] = $url;
  1327.                 break;
  1328.         } # end switch
  1329.     } # end function do_redirect
  1330.  
  1331. } # end class
  1332. ?>