我正在使用Ubercart产品和product_kit模块。这非常适用于从相关产品套件到包含的产品的链接,但我也希望从单个产品链接到它可能属于的任何套件。
我想我可以在SKU /型号上进行数据库搜索(轻松完成该部分),然后使用node_load($ nid)获取相关工具包。
到目前为止,我有这个:
function amh_shop_nodeapi(&$node, $op, $a3 = null, $a4 = null)
{
if ($node->type == 'product') {
if ($op == 'load') {
error_log("product::load");
$bundles = array();
$results = db_query('SELECT DISTINCT n.nid FROM {node} n RIGHT JOIN {uc_products} up ON up.nid = n.nid WHERE up.model LIKE "%s /%" OR up.model LIKE "%/ %s /%" OR up.model LIKE "%/ %s"', $node->model, $node->model, $node->model);
while ($bundle = db_fetch_object($results)) {
error_log("bundle::load");
$bundles[] = node_load($bundle->nid);
}
}
}
}
但是,由于产品套件也在加载产品,我最终会进行递归循环。
我想我的问题实际上分为两部分:
这篇文章标题的问题:如何防止这种递归?
可能会回答第一个问题的问题略有不同:我应该在加载节点时执行此操作,还是稍后在此过程中(例如,在查看或更改时)?
答案 0 :(得分:2)
嘿,有一个名为http://drupal.org/project/contemplate的模块。他们在该模块中有类似的递归问题,但他们通过设置recursion_limit找到了解决方法。
我不确定它是否能解决您的问题,但绝对值得通过他们的模块并搜索代码 contemplate_max_recursion_depth 。这可能会给你一些指示。
希望有所帮助......
答案 1 :(得分:0)
其中一个解决方案,就是不要为product_kit调用node_load,因此它不会为子产品调用node_load,通过db_query手动查询需要的数据:
function amh_shop_nodeapi(&$node, $op, $a3 = null, $a4 = null)
{
if ($node->type == 'product') {
if ($op == 'load') {
$bundles = array();
$results = db_query('SELECT n.nid, n.title FROM {node} n INNER JOIN {uc_product_kits} k ON n.nid=k.nid WHERE n.product_id=%d ORDER BY n.title', $node->nid);
while ($bundle = db_fetch_object($results)) {
$bundles[] = l($bundle->title, 'node/'.$bundle->nid);
}
}
}
$node->amh_bundles = $bundles; // Here's array of links to product_kits
}
答案 2 :(得分:0)
这个怎么样:它引入了一个递归变量检查。
function amh_shop_nodeapi(&$node, $op, $a3 = null, $a4 = null)
{
static $recursion_nid = NULL;
if ($node->type == 'product') {
if ($op == 'load') {
error_log("product::load");
$bundles = array();
$results = db_query('SELECT DISTINCT n.nid FROM {node} n RIGHT JOIN {uc_products} up ON up.nid = n.nid WHERE up.model LIKE "%s /%" OR up.model LIKE "%/ %s /%" OR up.model LIKE "%/ %s"', $node->model, $node->model, $node->model);
while ($bundle = db_fetch_object($results)) {
error_log("bundle::load");
if (isset($recursion_nid) && $recursion_nid == $nid) {
// recursion detected
}
else {
$recursion_nid = $node->nid;
$bundles[] = node_load($bundle->nid);
unset($recursion_nid);
}
}
}
}
}
答案 3 :(得分:-1)
你应该考虑像这样缓存数据。如果你一直在加载它真的会耗尽资源。我会考虑一个自定义模块,可以存储各个项目和相关工具包之间的关系。