2011-02-24 88 views
0

我正在使用Ubercart產品和product_kit模塊。這對於將相關產品套件鏈接到包含的產品非常有用,但我也想從單個產品鏈接到它可能包含的任何套件。如何防止用Drupal的node_load()進行無限遞歸?

我想我可以在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. 無論如何,可能會回答第一個問題的一個稍微不同的問題:我應該在加載節點時還是在後續過程中(例如,在視圖或更改過程中)執行此操作?

回答

2

嘿有一個叫http://drupal.org/project/contemplate的模塊。他們在這個模塊中有一個類似遞歸的問題,但他們通過設置recursion_limit找到了解決方法。

我不確定它是否解決了您的問題,但肯定會值得通過它們的模塊並搜索代碼contemplate_max_recursion_depth。這可能會給你一些指示。

希望它有幫助..

-1

你應該考慮像這樣緩存數據。如果你一直在加載它,它可能真的耗盡資源。我會考慮一個可以存儲單個項目和相關工具之間關係的自定義模塊。

+0

沒有真正回答我的任何問題。 – HorusKol 2011-02-28 02:55:53

0

One解決方案的,只是不要求product_kit node_load,這樣就不會調用node_load的子產品,通過查詢手動db_query需要DATAS:

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 
} 
+0

問題是 - 我想要的不僅僅是產品工具包的節點ID和標題,並且node_load似乎是最好的方法,以便在我需要額外的詳細信息的時候節省我不得不重寫查詢的時間。 。任何事件 - 我將此代碼移至視圖op – HorusKol 2011-02-28 22:34:12

+0

好主意,但不會促進重用。我只會設置節點ID並將它們變爲主題圖層中的鏈接。 – Rimian 2011-03-01 02:00:22

+0

Rimian我同意,應該有節點ID,我只是作爲例子。 2HorusKol,根據我對優化drupal的經驗,有時調用node_load並不適合每次調用(在此事件中調用的模塊過多),更好的方法是使用db_query,如果發生這種情況,緩存將有所幫助。 – Nikit 2011-03-01 02:14:57

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