Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 39
0.00% covered (danger)
0.00%
0 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
CargoHierarchyTree
0.00% covered (danger)
0.00%
0 / 39
0.00% covered (danger)
0.00%
0 / 6
240
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 addChild
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 newFromWikiText
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
30
 getLastNodeForLevel
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
12
 generateHierarchyStructureTableData
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
12
 computeLeftRight
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2/**
3 * CargoHierarchyTree - holds the tree for hierarchy inorder to implement Nested Set model for
4 * efficient storage and query of hierarchy fields.
5 *
6 * @author Feroz Ahmad
7 * @ingroup Cargo
8 */
9
10class CargoHierarchyTree {
11    public $mRootValue;
12    public $mChildren;
13    public $mLeft = 0;
14    public $mRight = 0;
15
16    public function __construct( $curTitle = '__pseudo_root__' ) {
17        $this->mRootValue = $curTitle;
18        $this->mChildren = [];
19    }
20
21    public function addChild( $child ) {
22        $this->mChildren[] = $child;
23    }
24
25    /**
26     * Turn a manually-created "structure", defined as a bulleted list
27     * in wikitext, into a tree. This code has been borrowed from PFTree class
28     * of Page Forms Extension
29     *
30     * @param string $wikitext
31     * @return self
32     */
33    public static function newFromWikiText( $wikitext ) {
34        // A dummy node (__pseudo_root__ is added so that
35        // multiple nodes can be added in the first level
36        $fullTree = new static();
37        $lines = explode( "\n", $wikitext );
38        foreach ( $lines as $line ) {
39            $numBullets = 0;
40            for ( $i = 0; $i < strlen( $line ) && $line[$i] == '*'; $i++ ) {
41                $numBullets++;
42            }
43            if ( $numBullets == 0 ) {
44                continue;
45            }
46            $lineText = trim( substr( $line, $numBullets ) );
47            $curParentNode = $fullTree->getLastNodeForLevel( $numBullets );
48            $curParentNode->addChild( new static( $lineText ) );
49        }
50        $fullTree->computeLeftRight();
51        return $fullTree;
52    }
53
54    public function getLastNodeForLevel( $level ) {
55        if ( $level <= 1 || count( $this->mChildren ) == 0 ) {
56            return $this;
57        }
58        $lastNodeOnCurLevel = end( $this->mChildren );
59        return $lastNodeOnCurLevel->getLastNodeForLevel( $level - 1 );
60    }
61
62    public function generateHierarchyStructureTableData() {
63        $tableData = [];
64        // Preorder traversal using Stack data structure
65        $stack = new SplStack();
66        $stack->push( $this );
67        while ( !$stack->isEmpty() ) {
68            /** @var CargoHierarchyTree $node */
69            $node = $stack->pop();
70            $row = [];
71            $row['_value'] = $node->mRootValue;
72            $row['_left'] = $node->mLeft;
73            $row['_right'] = $node->mRight;
74            $tableData[] = $row;
75            foreach ( array_reverse( $node->mChildren ) as $child ) {
76                $stack->push( $child );
77            }
78        }
79        return $tableData;
80    }
81
82    private function computeLeftRight( &$counter = 1 ) {
83        $this->mLeft = $counter;
84        $counter += 1;
85        // Visit mChildren of the current node
86        foreach ( $this->mChildren as $child ) {
87            $child->computeLeftRight( $counter );
88        }
89        $this->mRight = $counter;
90        $counter += 1;
91    }
92}