Originally Posted by
carlwhat
@mc12345678, doing what you will suggest will not solve @johnnyh's issue.
as far as i can tell, the problem is with the $language_id.
#1, it does not look like you have the DEFAULT_LANGUAGE set in the admin. that said, it looks to be a hidden configuration.
#2, it would still not work, as they are using the default language code as opposed to the languages_id.
This is why when writing code applicable to ZC that it is recommended to use the builtin ZC functions... They work regardless of underlying syntax.
Ie. in an environment that supports mysql_ only functions (way back when) a $db->Execute($sql); will work just as well as in an environment where mysqli_ functions are programmed into ZC and at the state of PHP >= 5.5 where mysql_ related functions are deprecated...
A mysqli_query without being performed against a mysqli object that has established a connection will fail. The code provided is written without a mysqli object... therefore mysqli_query($sql) will fail.
As to the "hidden" portion of the configuration, a constant that is defined in the configuration table for a default ZC system is loaded regardless of it being "hidden" or not. So, that plays no part in the assignment/usage.
I suggest the following code in either of two ways (both presented) one which is an upgrade to what they provided (mysql_ functions to mysqli_ functions), the other is significantly using ZC format/code.
Code:
<?php
require('includes/application_top.php');
header('Content-Type: application/rss+xml;charset=UTF-8');
ob_end_clean();
function encodeIfNeeded($text) {
if('utf-8' != strtolower(CHARSET)) {
$text = iconv(CHARSET, 'UTF-8', $text);
}
return $text;
}
function replace_problem_characters($text) {
$formattags = array("&");
$replacevals = array("&");
$text = str_replace($formattags, $replacevals, $text);
$in[] = '@&(amp|#038);@i'; $out[] = '&';
$in[] = '@&(#036);@i'; $out[] = '$';
$in[] = '@&(quot);@i'; $out[] = '"';
$in[] = '@&(#039);@i'; $out[] = '\'';
$in[] = '@&(nbsp|#160);@i'; $out[] = ' ';
$in[] = '@&(hellip|#8230);@i'; $out[] = '...';
$in[] = '@&(copy|#169);@i'; $out[] = '(c)';
$in[] = '@&(trade|#129);@i'; $out[] = '(tm)';
$in[] = '@&(lt|#60);@i'; $out[] = '<';
$in[] = '@&(gt|#62);@i'; $out[] = '>';
$in[] = '@&(laquo);@i'; $out[] = '«';
$in[] = '@&(raquo);@i'; $out[] = '»';
$in[] = '@&(deg);@i'; $out[] = '°';
$in[] = '@&(mdash);@i'; $out[] = '—';
$in[] = '@&(reg);@i'; $out[] = '®';
$in[] = '@&(–);@i'; $out[] = '-';
$text = preg_replace($in, $out, $text);
return $text;
}
function strip_html_tags($str) {
// $document should contain an HTML document.
// This will remove HTML tags, javascript sections
// and white space. It will also convert some
// common HTML entities to their text equivalent.
$search = array ("'<script[^>]*?>.*?</script>'si", // Strip out javascript
"'<[/!]*?[^<>]*?>'si", // Strip out HTML tags
//"'([rn])[s]+'", // Strip out white space
"'&(quot|#34);'i", // Replace HTML entities
// "'&(amp|#38);'i",
"'&(lt|#60);'i",
"'&(gt|#62);'i",
"'&(nbsp|#160);'i",
"'&(iexcl|#161);'i",
"'&(cent|#162);'i",
"'&(pound|#163);'i",
"'&(copy|#169);'i",
"'&#(d+);'e"); // evaluate as php
$replace = array ("",
"",
//"\1",
"\"",
"&",
"<",
">",
" ",
chr(160),
chr(161),
chr(162),
chr(163),
chr(169),
"chr(\1)");
return preg_replace($search, $replace, $str);
}
echo '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
?>
<rss xmlns:g="http://base.google.com/ns/1.0" version="2.0">
<channel>
<?php
echo '<title>Catalog Feed</title>'. "\n";
$store=mysqli_fetch_assoc(mysqli_query($db->link,"select * from ".DB_PREFIX."configuration where configuration_key='STORE_NAME'"));
echo '<link>'.HTTP_SERVER.DIR_WS_CATALOG.'</link>'. "\n";
echo '<description>Catalog Feed generated by StoreYa.com 2.1</description>'. "\n";
// * NOTICE OF LICENSE
// *
// * This source file is the property of StoreYa Feed LTD. and a part of its patent pending technology.
// * Using this file is allowed only for the purpose of importing web stores onto Facebook using the service of StoreYa Feed LTD.
// * Do NOT copy/edit/change this file or use it to any service other than the above.
$admin=mysqli_fetch_assoc(mysqli_query($db->link, "select * from ".DB_PREFIX."admin limit 0,1"));
echo '<lastBuildDate>'.date('m/d/Y H:is').'</lastBuildDate>'. "\n";
//echo '<copyright>Copyright '.date('Y').', '.$_SERVER['HTTP_HOST'].'</copyright>'. "\n";
if (isset($_GET['language_id'])) {
$lng = new language();
if (isset($_GET['language_id']) && zen_not_null($_GET['language_id'])) {
$lng->language['id'] = (int)$_GET['language_id'];
} else {
if (LANGUAGE_DEFAULT_SELECTOR=='Browser') {
$lng->get_browser_language();
} else {
$lng->set_language(DEFAULT_LANGUAGE);
}
}
$language_id = (zen_not_null($lng->language['id']) ? $lng->language['id'] : 1);
} else {
$language_id = $_SESSION['languages_id'];
}
$prdqry= mysqli_query($db->link, "select ".DB_PREFIX."products.products_id,products_price,products_price_sorter,products_image,products_name,products_description,products_url from ".DB_PREFIX."products,".DB_PREFIX."products_description where ".DB_PREFIX."products.products_status='1' and ".DB_PREFIX."products.products_id=".DB_PREFIX."products_description.products_id and ".DB_PREFIX."products_description.language_id='".$language_id."' order by ".DB_PREFIX."products.products_id ");
while($row=mysqli_fetch_assoc($prdqry))
{
echo '<item>'. "\n";
echo ' <title>'.strip_html_tags(replace_problem_characters(encodeIfNeeded($row['products_name']))).'</title>'. "\n";
echo ' <link>'. htmlentities(HTTP_SERVER.DIR_WS_CATALOG.'index.php?main_page=product_info&products_id='.$row['products_id']).'</link>'. "\n";
echo ' <description>'. htmlspecialchars(strip_html_tags(replace_problem_characters(encodeIfNeeded($row['products_description'])))).'</description>'. "\n";
echo ' <g:image_link>'.HTTP_SERVER.DIR_WS_CATALOG.'images/'.$row['products_image'].'</g:image_link>'. "\n";
echo ' <g:id>'.$row['products_id'].'</g:id>'. "\n";
echo ' <g:price>'.$row['products_price'].'</g:price>'. "\n";
echo ' <g:sale_price>'.$row['products_price_sorter'].'</g:sale_price>'. "\n";
$catqry=mysqli_query($db->link, "select categories_name from ".DB_PREFIX."categories_description,".DB_PREFIX."products_to_categories where language_id='".$language_id."' and ".DB_PREFIX."products_to_categories.categories_id=".DB_PREFIX."categories_description.categories_id and ".DB_PREFIX."products_to_categories.products_id='".$row['products_id']."'");
while($catrow=mysqli_fetch_assoc($catqry))
{
echo ' <g:product_type>'.strip_html_tags(replace_problem_characters(encodeIfNeeded($catrow['categories_name']))).'</g:product_type>'. "\n";
}
echo '</item>'. "\n";
}
echo '</channel>'. "\n";
echo '</rss>';
Written more for/with ZC code:
Code:
<?php
require('includes/application_top.php');
header('Content-Type: application/rss+xml;charset=UTF-8');
ob_end_clean();
function encodeIfNeeded($text) {
if('utf-8' != strtolower(CHARSET)) {
$text = iconv(CHARSET, 'UTF-8', $text);
}
return $text;
}
function replace_problem_characters($text) {
$formattags = array("&");
$replacevals = array("&");
$text = str_replace($formattags, $replacevals, $text);
$in[] = '@&(amp|#038);@i'; $out[] = '&';
$in[] = '@&(#036);@i'; $out[] = '$';
$in[] = '@&(quot);@i'; $out[] = '"';
$in[] = '@&(#039);@i'; $out[] = '\'';
$in[] = '@&(nbsp|#160);@i'; $out[] = ' ';
$in[] = '@&(hellip|#8230);@i'; $out[] = '...';
$in[] = '@&(copy|#169);@i'; $out[] = '(c)';
$in[] = '@&(trade|#129);@i'; $out[] = '(tm)';
$in[] = '@&(lt|#60);@i'; $out[] = '<';
$in[] = '@&(gt|#62);@i'; $out[] = '>';
$in[] = '@&(laquo);@i'; $out[] = '«';
$in[] = '@&(raquo);@i'; $out[] = '»';
$in[] = '@&(deg);@i'; $out[] = '°';
$in[] = '@&(mdash);@i'; $out[] = '—';
$in[] = '@&(reg);@i'; $out[] = '®';
$in[] = '@&(–);@i'; $out[] = '-';
$text = preg_replace($in, $out, $text);
return $text;
}
function strip_html_tags($str) {
// $document should contain an HTML document.
// This will remove HTML tags, javascript sections
// and white space. It will also convert some
// common HTML entities to their text equivalent.
$search = array ("'<script[^>]*?>.*?</script>'si", // Strip out javascript
"'<[/!]*?[^<>]*?>'si", // Strip out HTML tags
//"'([rn])[s]+'", // Strip out white space
"'&(quot|#34);'i", // Replace HTML entities
// "'&(amp|#38);'i",
"'&(lt|#60);'i",
"'&(gt|#62);'i",
"'&(nbsp|#160);'i",
"'&(iexcl|#161);'i",
"'&(cent|#162);'i",
"'&(pound|#163);'i",
"'&(copy|#169);'i",
"'&#(d+);'e"); // evaluate as php
$replace = array ("",
"",
//"\1",
"\"",
"&",
"<",
">",
" ",
chr(160),
chr(161),
chr(162),
chr(163),
chr(169),
"chr(\1)");
return preg_replace($search, $replace, $str);
}
echo '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
?>
<rss xmlns:g="http://base.google.com/ns/1.0" version="2.0">
<channel>
<?php
echo '<title>Catalog Feed</title>'. "\n";
// $store=mysqli_fetch_assoc(mysqli_query($db->link,"select * from ".DB_PREFIX."configuration where configuration_key='STORE_NAME'")); // in this "section" of code, $store is not even used and therefore there is no need to perform this query. If it was needed, then:
// $store=$db->Execute("select * from ".TABLE_CONFIGURATION." where configuration_key='STORE_NAME'"); // or if just need the value associated to that key:
// $store = zen_get_configuration_key_value('STORE_NAME');
?><link><?php echo zen_href_link(FILENAME_DEFAULT); ?></link>
<description>Catalog Feed generated by StoreYa.com 2.1</description>
<?php
// * NOTICE OF LICENSE
// *
// * This source file is the property of StoreYa Feed LTD. and a part of its patent pending technology.
// * Using this file is allowed only for the purpose of importing web stores onto Facebook using the service of StoreYa Feed LTD.
// * Do NOT copy/edit/change this file or use it to any service other than the above.
//$admin=mysqli_fetch_assoc(mysqli_query($db->link, "select * from ".DB_PREFIX."admin limit 0,1")); // The variable $admin is also not used in this "section" of code and reveals/provides access to information about the first admin record (admin_id, admin_name, admin_email, the encrypted password(s), etc... and could help lead to a security problem down the line.
// $admin= $db->Execute("select * from ".TABLE_ADMIN." limit 0,1");
?><lastBuildDate><?php echo date('m/d/Y H:is'); ?></lastBuildDate>
<?php
//echo '<copyright>Copyright '.date('Y').', '.$_SERVER['HTTP_HOST'].'</copyright>'. "\n";
if (isset($_GET['language_id'])) {
$lng = new language();
if (isset($_GET['language_id']) && zen_not_null($_GET['language_id'])) {
$lng->language['id'] = (int)$_GET['language_id'];
} else {
if (LANGUAGE_DEFAULT_SELECTOR=='Browser') {
$lng->get_browser_language();
} else {
$lng->set_language(DEFAULT_LANGUAGE);
}
}
$language_id = (zen_not_null($lng->language['id']) ? $lng->language['id'] : 1);
} else {
$language_id = $_SESSION['languages_id'];
}
$prdqry= $db->Execute("select p.products_id,p.products_price,p.products_price_sorter,p.products_image,pd.products_name,pd.products_description,pd.products_url from ".TABLE_PRODUCTS." p,".TABLE_PRODUCTS_DESCRIPTION." pd where p.products_status='1' and p.products_id=pd.products_id and pd.language_id=".(int)$language_id." order by p.products_id ");
while(!$prdqry->EOF)
{
$row = $prdqry->fields;
?><item>
<title><?php echo strip_html_tags(replace_problem_characters(encodeIfNeeded($row['products_name']))); ?></title>
<link><?php echo htmlentities(zen_href_link(zen_get_info_page((int)$row['products_id']), 'products_id='.(int)$row['products_id'])); ?></link>
<description><?php echo htmlspecialchars(strip_html_tags(replace_problem_characters(encodeIfNeeded($row['products_description'])))); ?></description> <g:image_link><?php echo HTTP_SERVER.DIR_WS_IMAGES.$row['products_image']; ?></g:image_link>
<g:id><?php echo $row['products_id']; ?></g:id>
<g:price><?php echo $row['products_price']; ?></g:price>
<g:sale_price><?php echo $row['products_price_sorter']; ?></g:sale_price>
<?php
$catqry=$db->Execute("select categories_name from ".TABLE_CATEGORIES_DESCRIPTION ." cd,".TABLE_PRODUCTS_TO_CATEGORIES." ptc where cd.language_id=".(int)$language_id." and ptc.categories_id=cd.categories_id and ptc.products_id=".(int)$row['products_id']);
while(!$catqry->EOF)
{
$catrow=$catqry->fields;
?> <g:product_type><?php echo strip_html_tags(replace_problem_characters(encodeIfNeeded($catrow['categories_name']))); ?></g:product_type>
<?php
$catqry->MoveNext();
}
?></item>
<?php
$prdqry->MoveNext();
}
?></channel>
</rss>
Further, just using the session value would discard the information sent to the module if they are truly sending a language_id in the uri, though one should investigate what they think the language_id should be, ie. is it a number (which is what that represents) or a version of a name of a language (ie. En for english, de for german, etc...).
Yes the "vendor" provided code is subject to sql injection, the above has been worked through to prevent that. The only other issue seen with the above code (taken from ZC functionality related to ZC 1.5.5) is that if the browser is to be used to detect the desired language, the browser doesn't return a "valid" language and at some point the initial language was removed after an additional was added, then the language information would not come back "favorable" because it looks like the language would be assigned to a non-existent language_id of 1. I plan to propose a PR to address that and instead use the default_language instead of 1.
Bookmarks