The problem resides in /includes/modules/attributes.php
This code is straight trash and when I have time I will fix it since nobody has been able to since osCommerce 2.2. Though I haven't had much time to look at it, I'm thinking something along the lines of:
Code:
$ripopts = $ridb->get_dataset_full(TABLE_PRODUCTS_OPTIONS,'products_options_id',$lqual.$options_order_by);
/**
* build a qualifier to pull the option values we need
* this gets backward for a minute because we need to associate the
* current product before we can associate the option info
*/
$qual = "WHERE products_id='$ripid' AND (";
foreach( $ripopts as $opt ){
$tmpid = $opt['products_options_id'];
$qual .= "options_id='$tmpid' OR ";
}
$qual = rtrim($qual,'OR ');
$qual .= ') ORDER BY products_options_sort_order,options_values_price';
$riattrib = $ridb->get_dataset_full(TABLE_PRODUCTS_ATTRIBUTES,'products_attributes_id',$qual);
// pull the option values now that we know the ones we need
$qual = $lqual.' AND (';
foreach( $riattrib as $attr ){
$tmpid = $attr['options_values_id'];
$qual .= "products_options_values_id='$tmpid' OR ";
}
$qual = rtrim($qual,'OR ');
$qual .= ')';
$rioptvals = $ridb->get_dataset_full(TABLE_PRODUCTS_OPTIONS_VALUES,'products_options_values_id',$qual);
// pull the options types and values associations (just grab them all, we associate later)
$rioptassoc = $ridb->get_dataset_full(TABLE_PRODUCTS_OPTIONS_VALUES_TO_PRODUCTS_OPTIONS,'products_options_values_to_products_options_id');
$riopttypes = $ridb->get_dataset_full(TABLE_PRODUCTS_OPTIONS_TYPES,'products_options_types_id');
// finally, put it all together in one geinormous array
$riattribs = array();
foreach( $ripopts as $popt ){
$optid = $popt['products_options_id'];
$opttype = $popt['products_options_type'];
$riattribs[$optid] = $popt;
$riattribs[$optid]['type'] == $riopttypes[$opttype]['products_options_types'];
foreach( $rioptassoc as $assoc ){
if( $assoc['products_options_id'] == $optid ){
$val_id = $assoc['products_options_values_id'];
$riattribs[$optid]['values'][$val_id] = $rioptvals[$val_id];
foreach( $riattrib as $atr ){
if( $atr['options_id'] == $optid && $atr['options_values_id'] == $val_id ){
$atrid = $atr['products_attributes_id'];
$riattribs[$optid]['values'][$val_id]['opts'][$atrid] = $atr;
}
}
}
}
} // ::whew::
// done with these
unset($riopts);
unset($riattrib);
unset($rioptvals);
unset($rioptassoc);
unset($riopttypes);
To gather all of the required attributes. You'll have to excuse me for using some of my own functions/classes, but the included ones are just nuts and you can pretty much tell what these do by thier names.
There's some notes about huge tables: Let's be honest here, if you're on localhost you'll not even notice this pulling 4000 options and, once pulled, you've completely eliminated all the BS you're doing with grabbing 1 ATTRIBUTE AT A TIME! As you currently have this nonsense:
Code:
// limit to 1 for performance when processing larger tables
$sql = "select count(*) as total
from " . TABLE_PRODUCTS_OPTIONS . " popt, " . TABLE_PRODUCTS_ATTRIBUTES . " patrib
where patrib.products_id='" . (int)$_GET['products_id'] . "'
and patrib.options_id = popt.products_options_id
and popt.language_id = '" . (int)$_SESSION['languages_id'] . "'" .
" limit 1";
Note, there much sorting built into my code, but that isn't all that hard to add. And no, I don't hit more than one table at a time because there isn't any reason to do so here.
While I'm here complaining: What editor are you guys using? You escape out to HTML every other line, often only to come back to PHP with no code in between: You've got your so=called "templates" all over the place - I honestly think osCommerce was easier to modify to look the way you wanted (http://hamak.ribosi.com - I do know what I'm talking about with osC): You don't use any form of standardized code layout (meaning you're not using whitespace in any sane manner - and what ever happened to 80 character lines?) and there's tons of places where you're writing conditionals as statements rather than blocks - as everyone knows you should not be doing.
I'll say this much - at least when I fix open source code, I give back to the community - just as the people at PHP-Nuke - or check out http://sourceforge.net/projects/mysqlcc - you guys who know your code can't honestly be running this code on production servers, can you?
I'll post here again when I'm done completely rewriting the "template" system to something that resembles sanity and cleaned up quite a few other issues, but don't expect that to be any time before 6 weeks or so.
This is just insane - it takes a full 27 seconds to reload the attributes manager page with a mere 88 attributes on a dual-opteron 246 system tweaked for apache from localhost - and don't give me this nonsense about "it must be your system", I run all sorts of code from this system just fine - including data parsers that can go through 150,000 records in the time it takes this attributes manager to load.
I really hate signing up to a site like this just to blow the developers away with all of this, but this code needs to be cleaned up badly. While I realize nobody's getting paid for the work they're doing here, it seems to me that every effort was made to make the code harder on the developers without any real gain in functionaliy or performance over osC - which, I thought, was the whole idea. While I may have only been working with zc for a couple days, it's been long enough for me to realize that this is not the case.
If you want the database class that goes with the above code, I've attached it here. It comes from RNuke, a heavily modified version of PHP-Nuke I've been working on (and going to be releasing to the public soon) and so based on the database class from PHP-Nuke. The template system I'll be including later also comes from this (though is completely my own work) and actually does separate form from function.
That's all I've got right now - flame on.