Skip to content

Instantly share code, notes, and snippets.

@bendo01
Last active December 25, 2015 17:39
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bendo01/7014197 to your computer and use it in GitHub Desktop.
Save bendo01/7014197 to your computer and use it in GitHub Desktop.
trying to create tree behavior
CREATE TABLE app_system.app_menus
(
id bigserial NOT NULL,
name character varying(255) NOT NULL,
title character varying(255),
url character varying(255) NOT NULL,
enable boolean NOT NULL,
parent_id bigint,
lft bigint,
rght bigint,
created timestamp without time zone,
modified timestamp without time zone,
created_by bigint,
modified_by bigint,
CONSTRAINT app_menus_pkey PRIMARY KEY (id)
)
WITH (
OIDS=FALSE
);
ALTER TABLE app_system.app_menus
OWNER TO bendo01;
<?php
namespace xPDPT\Models\AppSystem;
class AppMenus extends \Phalcon\Mvc\Model
{
protected $node;
protected $properties;
protected $children = array();
/**
*
* @var integer
*/
protected $id;
/**
*
* @var string
*/
protected $name;
/**
*
* @var string
*/
protected $title;
/**
*
* @var string
*/
protected $url;
/**
*
* @var string
*/
protected $enable;
/**
*
* @var integer
*/
protected $parentId;
/**
*
* @var integer
*/
protected $lft;
/**
*
* @var integer
*/
protected $rght;
/**
*
* @var string
*/
protected $created;
/**
*
* @var string
*/
protected $modified;
/**
*
* @var integer
*/
protected $createdBy;
/**
*
* @var integer
*/
protected $modifiedBy;
/**
* Method to set the value of field id
*
* @param integer $id
* @return $this
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* Method to set the value of field name
*
* @param string $name
* @return $this
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Method to set the value of field title
*
* @param string $title
* @return $this
*/
public function setTitle($title)
{
$this->title = $title;
return $this;
}
/**
* Method to set the value of field url
*
* @param string $url
* @return $this
*/
public function setUrl($url)
{
$this->url = $url;
return $this;
}
/**
* Method to set the value of field enable
*
* @param string $enable
* @return $this
*/
public function setEnable($enable)
{
$this->enable = $enable;
return $this;
}
/**
* Method to set the value of field parent_id
*
* @param integer $parent_id
* @return $this
*/
public function setParentId($parentId)
{
$this->parentId = $parentId;
return $this;
}
/**
* Method to set the value of field lft
*
* @param integer $lft
* @return $this
*/
public function setLft($lft)
{
$this->lft = $lft;
return $this;
}
/**
* Method to set the value of field rght
*
* @param integer $rght
* @return $this
*/
public function setRght($rght)
{
$this->rght = $rght;
return $this;
}
/**
* Method to set the value of field created
*
* @param string $created
* @return $this
*/
public function setCreated($created)
{
$this->created = $created;
return $this;
}
/**
* Method to set the value of field modified
*
* @param string $modified
* @return $this
*/
public function setModified($modified)
{
$this->modified = $modified;
return $this;
}
/**
* Method to set the value of field created_by
*
* @param integer $created_by
* @return $this
*/
public function setCreatedBy($createdBy)
{
$this->createdBy = $createdBy;
return $this;
}
/**
* Method to set the value of field modified_by
*
* @param integer $modified_by
* @return $this
*/
public function setModifiedBy($modifiedBy)
{
$this->modified_by = $modified_by;
return $this;
}
/**
* Returns the value of field id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Returns the value of field name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Returns the value of field title
*
* @return string
*/
public function getTitle()
{
return $this->title;
}
/**
* Returns the value of field url
*
* @return string
*/
public function getUrl()
{
return $this->url;
}
/**
* Returns the value of field enable
*
* @return string
*/
public function getEnable()
{
return $this->enable;
}
/**
* Returns the value of field parent_id
*
* @return integer
*/
public function getParentId()
{
return $this->parentId;
}
/**
* Returns the value of field lft
*
* @return integer
*/
public function getLft()
{
return $this->lft;
}
/**
* Returns the value of field rght
*
* @return integer
*/
public function getRght()
{
return $this->rght;
}
/**
* Returns the value of field created
*
* @return string
*/
public function getCreated()
{
return $this->created;
}
/**
* Returns the value of field modified
*
* @return string
*/
public function getModified()
{
return $this->modified;
}
/**
* Returns the value of field created_by
*
* @return integer
*/
public function getCreatedBy()
{
return $this->createdBy;
}
/**
* Returns the value of field modified_by
*
* @return integer
*/
public function getModifiedBy()
{
return $this->modifiedBy;
}
/**
* Initialize method for model.
*/
public function initialize()
{
$this->setSchema("app_system");
}
public function getSource()
{
return 'app_menus';
}
/**
* Independent Column Mapping.
*/
public function columnMap() {
return array(
'id' => 'id',
'name' => 'name',
'title' => 'title',
'url' => 'url',
'enable' => 'enable',
'parent_id' => 'parentId',
'lft' => 'lft',
'rght' => 'rght',
'created' => 'created',
'modified' => 'modified',
'created_by' => 'createdBy',
'modified_by' => 'modifiedBy'
);
}
public function startUp()
{
$results = null;
if (!isset($this->properties)) {
$this->properties = $this->columnMap();
}
if (!isset($this->node)) {
$results = $this->find(
array(
'order' => 'lft ASC'
)
);
$this->node = array();
}
if (!empty($results)) {
foreach ($results as $result) {
$this->node[$result->id] = $result;
}
}
}
public static function cmpLeft($a, $b)
{
return $a->lft > $b->lft;
}
public function reOrderLookUpArray()
{
//usort($this->node, array('ModelBaseName','cmpLeft'));
usort($this->node, array($this,"cmpLeft"));
}
public function getChildren($id = null, $childrenOnly = false, $typeObject = true){
$this->startUp();
$parentHasIn = false;
$arrKeys = $this->columnMap();
$returnArray = array();
$children = array();
// if parent node exists in the lookup array OR we're looking for the topmost nodes
if (!empty($id) && !empty($this->node[$id])) {
foreach ($this->node as $node) {
// node's "left" is higher than parent node's "left"
// node's "left" is smaller than parent node's "right"
if (($node->parentId == $id) && ($this->node[$id]->lft < $node->lft) && ($node->lft < $this->node[$id]->rght)) {
if (!$parentHasIn && !$childrenOnly) {
$children[] = $this->node[$id];
$parentHasIn = true;
}
$children[] = $node;
}
}
}
$returnArray = $children;
if(!$typeObject) {
$returnArray = array();
if (!empty($children)) {
$i=0;
foreach ($children as $child) {
foreach ($arrKeys as $key => $value) {
$returnArray[$i][$value] = $child->{$value};
}
$i++;
}
}
}
return $returnArray;
}
public function getChildrenBasedOnParentId($parentId = null)
{
$arrKeys = $this->columnMap();
$returnArray = array();
$children = array();
$this->node = $this->find(
array(
'conditions' => 'parentId is null'
)
);
if (!empty($parentId)) {
$this->node = $this->find(
array(
'conditions' => 'parentId = '.$parentId
)
);
}
if (!empty($this->node)) {
foreach ($this->node as $node) {
// node's "left" is higher than parent node's "left"
// node's "left" is smaller than parent node's "right"
if (($node->parentId == $parentId)) {
$children[] = $node;
}
}
}
if (!empty($children)) {
$i=0;
foreach ($children as $child) {
foreach ($arrKeys as $key => $value) {
$returnArray[$i][$value] = $child->{$value};
}
$i++;
}
}
return $returnArray;
}
public function getChildrenCount($id = null)
{
$result = 0;
$this->startUp();
if (!empty($this->node) && !empty($id)) {
$result = 0;
foreach ($this->node as $node) {
if ($node->parentId == $id) {
$result++;
}
}
}
return $result;
}
public function getDescendantsCount($id = null)
{
$result = 0;
$this->startUp();
if (!empty($this->node) && !empty($id) && !empty($this->node[$id])) {
$result = ($this->node[$id]->rght - $this->node[$id]->lft - 1) / 2;
}
return $result;
}
public function getParent($id = null)
{
$node = null;
if (!empty($id)) {
$result = $this->findFirst($id);
$node = $this->findFirst($result->parentId);
}
return $node;
}
public function getPath($id = null)
{
$parents = array();
$this->startUp();
if (!empty($id) && !empty($this->node[$id])) {
foreach ($this->node as $node) {
if( ($node->lft < $this->node[$id]->lft) && ($node->rght > $this->node[$id]->rght)) {
$parents[] = $node;
}
}
}
return $parents;
}
public function generateSeparator($name = null, $count = 0, $separator = '-')
{
$returnStr = $name;
if(!empty($name) && $count > 0) {
$tempStr = '';
for($i=0; $i<$count; $i++) {
$tempStr.=$separator;
}
$returnStr = $tempStr.$name;
}
return $returnStr;
}
public function getSelectables($separator = '-')
{
$this->startUp();
$returnArray = array();
foreach ($this->node as $node) {
$returnArray[] = $this->generateSeparator($node->name, count($this->getPath($node->id)), $separator);
}
return $returnArray;
}
public function getAllRoot($typeObject = true)
{
$returnArray = null;
$arrKeys = $this->columnMap();
$rootArr = $this->find(
array(
'conditions' => 'parentId is null',
'order' => 'lft ASC'
)
);
$returnArray = $rootArr;
if(!$typeObject) {
$returnArray = null;
if (!empty($rootArr)) {
$i=0;
foreach ($rootArr as $root) {
foreach ($arrKeys as $key => $value) {
$returnArray[$i][$value] = $root->{$value};
}
$i++;
}
}
}
return $returnArray;
}
public function getSubtree($childrenData = array())
{
if(!empty($childrenData)) {
$i = 0;
foreach ($childrenData as $childData) {
if ($this->getChildrenCount($childData['id']) > 0 ) {
$childrenData[$i]['children'] = $this->getChildren($childData['id'], true, false);
$childrenData[$i]['children'] = $this->getSubtree($childrenData[$i]['children']);
}
$i++;
}
}
return $childrenData;
}
public function getTree()
{
$roots = $this->getAllRoot(false);
if (!empty($roots)) {
$i=0;
foreach ($roots as $root) {
if ($this->getChildrenCount($root['id']) > 0 ) {
$roots[$i]['children'] = $this->getChildren($root['id'], true, false);
$roots[$i]['children'] = $this->getSubtree($roots[$i]['children']);
}
$i++;
}
}
return $trees;
}
public function getChildForRebuildTree($parentId = null)
{
$returnArray = null;
$arrKeys = $this->columnMap();
$returnArray = array();
$children = null;
if (!empty($parentId)) {
$children = $this->find(
array(
'conditions' => 'parentId = '.$parentId,
'order' => 'id'
)
);
$returnArray = array();
if (!empty($children)) {
$i=0;
foreach ($children as $child) {
foreach ($arrKeys as $key => $value) {
$returnArray[$i][$value] = $child->{$value};
}
$i++;
}
}
}
else {
$children = $this->find(
array(
'conditions' => 'parentId is null',
'order' => 'id'
)
);
$returnArray = array();
if (!empty($children)) {
$i=0;
foreach ($children as $child) {
foreach ($arrKeys as $key => $value) {
$returnArray[$i][$value] = $child->{$value};
}
$i++;
}
}
}
/*
echo '<pre>';
print_r($returnArray);
echo '</pre>';
exit;
*/
return $returnArray;
}
public function hasChildrenForRebuildTree($parentId = null)
{
$returnBoolean = false;
$count = count($this->getChildForRebuildTree($parentId));
if ($count > 0) {
$returnBoolean = true;
}
return $returnBoolean;
}
public function rebuildTree($counter = 1, $parentId = null)
{
$limit = 100;
$children = $this->getChildForRebuildTree($parentId);
$hasChildren = (bool)$children;
if ($parentId !== null) {
if ($hasChildren) {
$this->getDi()->get('db')->query('UPDATE '.$this->getSchema().'.'.$this->getSource().' SET lft = '.$counter.' WHERE id = '.$parentId);
$counter++;
}
else {
$this->getDi()->get('db')->query('UPDATE '.$this->getSchema().'.'.$this->getSource().' SET lft = '.$counter.', rght = '.($counter+1).' WHERE id = '.$parentId);
$counter += 2;
}
}
while ($children) {
foreach ($children as $row) {
$counter = $this->rebuildTree($counter, $row['id']);
}
if (count($children) !== $limit) {
break;
}
$children = $this->getChildForRebuildTree($parentId);
}
if ($parentId !== null && $hasChildren) {
$this->getDi()->get('db')->query('UPDATE '.$this->getSchema().'.'.$this->getSource().' SET rght = '.$counter.' WHERE id = '.$parentId);
$counter++;
}
return $counter;
}
public function addNewNode($data = null)
{
//check if node is root (parentId == null)
//check if node is child but parentId currently has no children
//check if node is child and parentId currently has children
}
public function editNode()
{
//check if update only data and not parentId, left, and right
//check if update include change on parentId
}
public function deleteNode()
{
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment