如何使用 Drupal 的 node_load() 防止无限递归?

发布于 2024-10-19 02:37:35 字数 1044 浏览 2 评论 0原文

我正在使用 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);
            }
        }
    }
}

但是,因为产品套件也在加载产品,所以我最终陷入了递归循环。

我想我的问题实际上分为两部分:

  1. 作为这篇文章标题的问题:如何防止这种递归?

  2. 无论如何,可能回答第一个问题的问题略有不同:我应该在加载节点时执行此操作,还是在加载过程的后期(例如,在查看或更改时)执行此

I'm using the Ubercart product and product_kit modules. This is great at linking from the relevant product kit to the products which are included, but I also want to link from the individual product to any kits it may be part of.

I figured I could do a database search on the SKU/Model number (got that part done easily), and then use node_load($nid) to get the related kit.

I have this so far:

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);
            }
        }
    }
}

But, because the product kits are also loading the products, I end up in a recursive loop.

I guess my question actually comes in two parts:

  1. The question that is the title of this post: how do I prevent this recursion?

  2. Slightly different question that probably answers the first one anyway: should I be doing this when the node is being loaded, or later in the process (for example, at view or alter)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

毅然前行 2024-10-26 02:37:35

嘿,有一个名为 http://drupal.org/project/contemplate 的模块。他们在该模块中遇到了类似的递归问题,但他们通过设置 recursion_limit 找到了解决方法。

我不确定它是否能解决您的问题,但绝对值得浏览他们的模块并搜索代码以查找contemplate_max_recursion_depth。这可能会给你一些指示。

希望有帮助..

Hey there is a module called http://drupal.org/project/contemplate. They had a similar problem of recursion within that module, but they figured out a workaround for it by setting a recursion_limit.

I am not sure if it solves your problem, but it will definitely be worth going through their module and search the code for contemplate_max_recursion_depth. That might give you some pointers.

Hope it helps..

ま柒月 2024-10-26 02:37:35

解决方案之一,就是不要对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
}

One of solutions, just don't call node_load for product_kit, so it will not call node_load for subproducts, query need datas manually via 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
}
注定孤独终老 2024-10-26 02:37:35

怎么样:它引入了递归变量检查。

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);
                }
            }
        }
    }
}

What about this: It introduces a recursion variable check.

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);
                }
            }
        }
    }
}
柒夜笙歌凉 2024-10-26 02:37:35

你应该考虑像这样缓存数据。如果你一直加载它,它真的会耗尽资源。我会考虑一个自定义模块,它可以存储各个项目和关联套件之间的关系。

you should consider cacheing data like this. If you're loading it all the time it could really drain resources. I would consider a custom module that can store a relationship between individual projects and associated kits.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文