      1:   2:   3:   4:   5:   6:   7:   8:   9:  10:  11:  12:  13:  14:  15:  16:  17:  18:  19:  20:  21:  22:  23:  24:  25:  26:  27:  28:  29:  30:  31:  32:  33:  34:  35:  36:  37:  38:  39:  40:  41:  42:  43:  44:  45:  46:  47:  48:  49:  50:  51:  52:  53:  54:  55:  56:  57:  58:  59:  60:  61:  62:  63:  64:  65:  66:  67:  68:  69:  70:  71:  72:  73:  74:  75:  76:  77:  78:  79:  80:  81:  82:  83:  84:  85:  86:  87:  88:  89:  90:  91:  92:  93:  94:  95:  96:  97:  98:  99: 100: 101:

    <?php

    namespace WPGMZA;

    class CategoryTreeNode implements \JsonSerializable
    {
        public $id;
        public $name;
        public $children;
        public $parent;
        public $marker_count = 0;

        public function __construct($parent=null)
        {
            $this->children = array();
        }

        public function jsonSerialize()
        {
            return array(
                'id'            => (int)$this->id,
                'name'          => $this->category_name,
                'icon'          => $this->category_icon,
                'priority'      => (int)$this->priority,
                'children'      => $this->children,
                'marker_count'  => (int)$this->marker_count
            );
        }

        public function getChildByID($id)
        {
            if($this->id == $id)
                return $this;

            foreach($this->children as $child)
            {
                if($result = $child->getChildByID($id))
                    return $result;
            }

            return null;
        }

        public function getAncestors()
        {
            $result = array();

            for($node = $this->parent; $node != null; $node = $node->parent)
                $result[] = $node;

            return $result;
        }

        public function getDescendants()
        {
            $result = array();

            foreach($this->children as $child)
            {
                $result[] = $child;
                $result = array_merge($result, $child->getDescendants());
            }

            return $result;
        }

        public function getLeafNodes()
        {
            $result = array();
            $descendants = $this->getDescendants();

            foreach($descendants as $node)
                if(empty($node->children))
                    $result[] = $node;

            return $result;
        }

        public function toJsTreeStructure()
        {
            $obj = array(
                'id'        => $this->id
            );

            if(!empty($this->category_name))
                $obj['text'] = $this->category_name;
            else if(!empty($this->name))
                $obj['text'] = $this->name;

            if(!empty($this->children))
            {
                $obj['children'] = array();

                foreach($this->children as $child)
                    $obj['children'][] = $child->toJsTreeStructure();
            }

            return $obj;
        }
    }