Skip to content

Commit

Permalink
Add closure table for nested collections
Browse files Browse the repository at this point in the history
  • Loading branch information
mah0001 committed May 14, 2024
1 parent c6c01d1 commit 182fa32
Show file tree
Hide file tree
Showing 2 changed files with 305 additions and 2 deletions.
260 changes: 260 additions & 0 deletions application/models/Collection_tree_model.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,260 @@
<?php



/**
*
* Collections tree model
*
*/
class Collection_tree_model extends CI_Model {


private $fields=array(
'parent_id',
'child_id',
'depth'
);

function __construct()
{
parent::__construct();
}


/**
*
* insert
*
*/
function insert($parent_id,$child_id)
{
$data=array(
'parent_id'=>$parent_id,
'child_id'=>$child_id,
'depth'=>0
);

if ($parent_id==$child_id){

if ($this->get_item($parent_id,$child_id,0)){
return true;
}

return $this->db->insert('editor_collections_tree',$data);
}

$sql='insert into editor_collections_tree(parent_id, child_id, depth)
select p.parent_id, c.child_id, p.depth+c.depth+1
from editor_collections_tree p, editor_collections_tree c
where p.child_id='. $this->db->escape($parent_id) .' and c.parent_id='. $this->db->escape($child_id) .';';

$result=$this->db->query($sql);
return $result;
}

/**
*
* Delete collection tree
*
* - deletes node + all children of the parent_id
*
*/
function delete($parent_id)
{
/*
note: note supported by MYSQL
delete from editor_collections_tree
where child_id in (select child_id from editor_collections_tree where parent_id=28)
*/

//$this->db->where('child_id in (select child_id from editor_collections_tree where parent_id='. $this->db->escape($parent_id) .')');
//return $this->db->delete('editor_collections_tree');

//get list of all children ids
$delete_list=$this->select_collection_tree_nodes($parent_id);

if (!$delete_list){
return true;
}

//delete all children
$this->db->where_in('child_id',$delete_list);
return $this->db->delete('editor_collections_tree');
}


function collections_tree_by_user_access($user_id)
{
$sql='select ect.parent_id,ect.child_id,ect.depth,c.* from editor_collections_tree ect
inner join editor_collections c on ect.child_id=c.id
where ect.parent_id in (
select c.id from editor_collections c
inner join editor_collections_tree t on c.id = t.parent_id
where t.child_id in (
select ect.child_id from editor_collections_tree ect
inner join editor_collections c on ect.child_id=c.id
where ect.parent_id in (
select c.id from editor_collections c
inner join editor_collections_tree t on c.id = t.parent_id
inner join editor_collection_access eca on eca.collection_id=c.id
where eca.user_id='. $this->db->escape($user_id) . '
)
) and c.pid is null
)
order by ect.child_id,ect.parent_id,ect.id,ect.depth;';


$items=$this->db->query($sql)->result_array();

//create tree
$tree=$this->build_collection_tree($items);

return $tree;
}

/**
*
* Return all children of a collection node
*
*/
function select_collection_tree_nodes($parent_id)
{
/*
select * from editor_collections_tree
where child_id in (select child_id from editor_collections_tree where parent_id=28)
*/

$this->db->select('parent_id');
$this->db->where('child_id in (select child_id from editor_collections_tree where parent_id='. $this->db->escape($parent_id) .')');
$result= $this->db->get('editor_collections_tree')->result_array();

$output=array();
foreach($result as $row){
$output[]=$row['parent_id'];
}
return $output;
}



function get_item($parent_id,$child_id,$depth)
{
$this->db->select('*');
$this->db->where('parent_id',$parent_id);
$this->db->where('child_id',$child_id);
$this->db->where('depth',$depth);
$result=$this->db->get('editor_collections_tree')->row_array();
return $result;
}


function select($parent_id)
{
$sql='select * from editor_collections_tree where parent_id='. $this->db->escape($parent_id) .';';
$result=$this->db->query($sql);
return $result->result_array();
}

function truncate_tree()
{
$this->db->truncate('editor_collections_tree');
}

function get_tree($parent_id=null)
{
$items=$this->get_tree_flat($parent_id);

$tree=array();
if ($parent_id){
$tree=$this->get_tree_root($parent_id);
$tree['items']=$this->build_collection_tree($items,$parent_id);
}else{
$tree=$this->build_collection_tree($items,$parent_id);
}
return $tree;
}

function get_tree_root($id)
{
$this->db->select('*');
$this->db->where('id',$id);
$result=$this->db->get('editor_collections')->row_array();
return $result;
}

private function build_collection_tree(array &$collections, $parentId = 0)
{
$output = array();

foreach ($collections as $collection) {
if ($collection['pid'] == $parentId) {
$children = $this->build_collection_tree($collections, $collection['id']);
if ($children) {
$collection['items'] = $children;
}
$output[] = $collection;
unset($collections[$collection['id']]);
}
}
return $output;
}


/*function build_tree_closure(&$collections, $depth=0, $parent_id=null)
{
$output=array();
foreach($collections as $idx=>$collection){
if ($collection['depth']==$depth){
//match parent_id if not null
if ($parent_id && $collection['parent_id']!=$parent_id){
continue;
}
//find children
$children=$this->build_tree_closure($collections,$depth+1,$collection['parent_id']);
if ($children){
$collection['items']=$children;
}
$output[]=$collection;
unset($collections[$idx]);
}
}
return $output;
}*/


function get_tree_flat($parent_id=null)
{
$this->db->select('ect.parent_id,ect.child_id,ect.depth,c.*');
$this->db->from('editor_collections_tree ect');
$this->db->join('editor_collections c','ect.child_id=c.id');

if ($parent_id){
$this->db->where('ect.parent_id',$parent_id);
}else{
$this->db->where('ect.parent_id in (select id from editor_collections where pid is null)');
}

$this->db->order_by('ect.depth','asc');
$this->db->order_by('c.title','asc');

$result=$this->db->get()->result_array();
return $result;
}


function get_all_collections_list()
{
$this->db->select('*');
$this->db->order_by('pid','asc');
return $this->db->get('editor_collections')->result_array();
}



}
47 changes: 45 additions & 2 deletions install/schema.mysql.sql
Original file line number Diff line number Diff line change
Expand Up @@ -1377,7 +1377,7 @@ LOCK TABLES `roles` WRITE;
/*!40000 ALTER TABLE `roles` DISABLE KEYS */;
insert into roles(id,name,description, weight, is_admin, is_locked) values
(1,'admin','It is the site administrator and has access to all site content', 0,1,1),
(2,'user','General user account with no access to site administration', 0,1,1);
(2,'user','General user account with no access to site administration', 0,0,1);
/*!40000 ALTER TABLE `roles` ENABLE KEYS */;
UNLOCK TABLES;

Expand Down Expand Up @@ -1746,4 +1746,47 @@ CREATE TABLE `audit_logs` (


alter table editor_templates modify column description text;
alter table editor_templates add instructions text;
alter table editor_templates add instructions text;



drop table if exists editor_code_lists;

CREATE TABLE editor_code_lists(
pk_id int NOT NULL AUTO_INCREMENT,
id varchar(100) not null,
agency_id varchar(100) not null,
name varchar(300) not null,
description varchar(300) default null,
version varchar(30) default null,
created int default null,
changed int default null,
created_by int DEFAULT null,
changed_by int default null,
PRIMARY KEY (`pk_id`),
UNIQUE KEY `cl_id` (`id`,`agency_id`, `version`)
);

CREATE TABLE editor_code_list_items(
pk_id int NOT NULL AUTO_INCREMENT,
cl_id int not null,
id varchar(100) not null,
name varchar(300) not null,
description varchar(300) default null,
created int default null,
changed int default null,
created_by int DEFAULT null,
changed_by int default null,
PRIMARY KEY (`pk_id`),
UNIQUE KEY `cl_item_id` (`id`,`cl_id`)
);


CREATE TABLE `editor_collections_tree` (
`id` int NOT NULL AUTO_INCREMENT,
`parent_id` int DEFAULT NULL,
`child_id` int DEFAULT NULL,
`depth` int DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `idx_closure` (`parent_id`,`child_id`,`depth`)
) ENGINE=InnoDB AUTO_INCREMENT=1;

0 comments on commit 182fa32

Please sign in to comment.