簡體   English   中英

使用Codeigniter關閉表顯示分層數據

[英]Displaying heirarchical data with Codeigniter closure table

使用Codeigniter,我需要顯示組織列表。 一些組織將有子組織,也可能有子組織的子組織,因此,需要在其上級下面的列表中顯示,如果願意的話,可以縮進。

我使用閉合表存儲組織層次結構,該結構非常適合插入,選擇子項等,但是在單個列表/查詢中選擇所有組織及其子項時遇到了麻煩。

組織表:

CREATE TABLE IF NOT EXISTS `organisations` (
  `org_id` INT NOT NULL AUTO_INCREMENT,
  `org_name` VARCHAR(60) NOT NULL,
  `address1` VARCHAR(40) NULL DEFAULT NULL,
  `address2` VARCHAR(40) NULL DEFAULT NULL,
  `address3` VARCHAR(40) NULL DEFAULT NULL,
  `town` VARCHAR(20) NULL DEFAULT NULL,
  `county` VARCHAR(20) NULL DEFAULT NULL,
  `pcode` VARCHAR(10) NULL DEFAULT NULL,
  `phone` VARCHAR(12) NULL DEFAULT NULL,
  `support_email` VARCHAR(60) NOT NULL,
  `active` TINYINT(4) NULL DEFAULT '1',
  PRIMARY KEY (`organisation_id`))
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;

還有org_hierarchy表

CREATE TABLE IF NOT EXISTS `org_hierarchy` (
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  `ancestor` INT(11) NOT NULL,
  `descendant` INT(11) NOT NULL,
  `lvl` INT(11) NOT NULL,
  PRIMARY KEY (`id`))
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;

這是我在模型中用來查詢數據庫並獲取組織子級的方法:

public function get_children($org_id, $node_id = 0, $self = TRUE, $level = TRUE){

    $this->db->select('t.org_id,t.org_name,t.org_label');
    $this->db->from($this->closure_table." c1");
    $this->db->join($this->table.' t','t.area_id = c1.descendant');
    $this->db->join($this->closure_table.' c2', 'c2.lvl IN(1) AND c2.descendant = c1.descendant','LEFT');
    $this->db->where('c1.ancestor',$node_id);
    $this->db->where('t.org_id',$org_id);

    if(!$self){$this->db->where('c1.descendant <>', $node_id);}

    if($level){$this->db->where('c1.lvl = ', $level);}

    $query = $this->db->get();

    if(!$query->num_rows()){return FALSE;}

    $result = $query->result();

    return $result;
}

但是,如何修改此查詢以顯示按上級組織分組的所有組織的完整列表?

我可以使用以下查詢查詢並獲得一個組織及其子級,但是如何修改查詢以使所有組織及其子級合並在一起? 我一定要靠近嗎?

SELECT o.* FROM organisations o
    JOIN org_hierarchy h
        ON (o.org_id = h.descendant)
    WHERE h.ancestor = 3

我嘗試了很多方法,但似乎無法更改它以包括所有組織?

org_hierarchy表的轉儲

mysql> SELECT * FROM org_hierarchy
    -> ;
+----+----------+------------+-----+
| id | ancestor | descendant | lvl |
+----+----------+------------+-----+
|  1 |        2 |          2 |   0 |
|  2 |        3 |          3 |   0 |
|  3 |        4 |          4 |   0 |
|  4 |        3 |          5 |   1 |
|  5 |        5 |          5 |   0 |
|  7 |        3 |          6 |   2 |
|  8 |        5 |          6 |   1 |
|  9 |        6 |          6 |   0 |
+----+----------+------------+-----+

好了,下面您將找到一個示例如何實現您想要的

您的模型應如下所示:

class Organisations_Model extends CI_Model
{

    private $arrOrganisationsGroupedByParent = array();
    private $objOrganisationsTree = false;

    public function loadOrganisations()
    {
        $query = $this->db
            ->select('o.*, if (oh.ancestor!=o.org_id, oh.ancestor, 0) AS parent', false)
            ->from("organisations o")
            ->join("org_hierarchy AS oh", "o.org_id = oh.descendant","left")
            ->get();

        $arrOrganisations = $query->result("Organisations_Object");

        foreach($arrOrganisations AS $objItem)
        {
            $this->arrOrganisationsGroupedByParent[$objItem->parent][] = $objItem;
        }
    }

    public function getTree()
    {
        $this->loadOrganisations();
        $this->objOrganisationsTree = new Organisations_Object();
        $this->createTree($this->objOrganisationsTree);
        return $this->objOrganisationsTree;
    }


    private function createTree($node)
    {
        if (isset($this->arrOrganisationsGroupedByParent[$node->org_id]))
        {
            foreach($this->arrOrganisationsGroupedByParent[$node->org_id] AS $objItem)
            {
                //echo $objItem->org_id."<br />";
                $node->addChild($objItem);
            }
        }

        foreach($node->arrChildObjects AS $objChild)
        {
            $this->createTree($objChild);
        }
    }
}

class Organisations_Object
{
    public $arrChildObjects = array();
    public $org_id = 0;
    public $parent = -1;

    public function addChild($node)
    {
        $this->arrChildObjects[] = $node;
    }
}

注意:您的模型中還有一個名為Organisations_Object的附加類-不要錯過該類!

之后,只需在Controller中調用getTree方法即可。

作為控制器的一個示例,只需將這兩個函數放入並從瀏覽器中調用

public function testtree()
{
    $this->load->model("Organisations_Model");
    $objTree = $this->Organisations_Model->getTree();
    $this->printTree($objTree);
}

private function printTree($objTree)
{
    echo "<ul>";

    foreach($objTree->arrChildObjects AS $objItem)
    {
        echo "<li>".$objItem->org_id."#".$objItem->org_name;
        if (count($objItem->arrChildObjects) > 0)
        {
            $this->printTree($objItem);
        }
        echo "</li>";
    }
    echo "</ul>";

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM