| 1 |  |  | <?php | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3 |  |  | namespace Nayjest\Tree; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 5 |  |  | use Nayjest\Tree\Utils\TreeBuilder; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 6 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 7 |  |  | class Utils | 
            
                                                                                                            
                            
            
                                    
            
            
                | 8 |  |  | { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 9 |  |  |     private static $treeBuilder; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 10 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 11 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 12 |  |  |      * @return TreeBuilder | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 13 |  |  |      */ | 
            
                                                                        
                            
            
                                    
            
            
                | 14 |  |  |     public static function getDefaultTreeBuilder() | 
            
                                                                        
                            
            
                                    
            
            
                | 15 |  |  |     { | 
            
                                                                        
                            
            
                                    
            
            
                | 16 |  |  |         if (!self::$treeBuilder) { | 
            
                                                                        
                            
            
                                    
            
            
                | 17 |  |  |             self::$treeBuilder = new TreeBuilder(); | 
            
                                                                        
                            
            
                                    
            
            
                | 18 |  |  |         } | 
            
                                                                        
                            
            
                                    
            
            
                | 19 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 20 |  |  |         return self::$treeBuilder; | 
            
                                                                        
                            
            
                                    
            
            
                | 21 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 22 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 23 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 24 |  |  |      * Builds tree from plain nodes based on configuration. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 25 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 26 |  |  |      * @param array           $config     multidimensional array that represents tree structure | 
            
                                                                                                            
                            
            
                                    
            
            
                | 27 |  |  |      * @param NodeInterface[] $plainItems nodes that must be organized to tree | 
            
                                                                                                            
                            
            
                                    
            
            
                | 28 |  |  |      * @param int             $flags      specifies tree building options, default: TreeBuilder::NORMALIZE_CONFIG; see TreeBuilder constants | 
            
                                                                                                            
                            
            
                                    
            
            
                | 29 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 30 |  |  |      * @return NodeInterface[] items organized to tree structure; array keys are not preserved | 
            
                                                                                                            
                            
            
                                    
            
            
                | 31 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 32 |  |  |     public static function buildTree(array $config, array $plainItems, $flags = TreeBuilder::NORMALIZE_CONFIG) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 33 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 34 |  |  |         return self::getDefaultTreeBuilder()->build($config, $plainItems, $flags); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 35 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 36 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 37 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 38 |  |  |      * Applies callback to root node, if it's existing and further descendant nodes directly after adding to tree. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 39 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 40 |  |  |      * @param callable      $callback    function to apply | 
            
                                                                                                            
                            
            
                                    
            
            
                | 41 |  |  |      * @param NodeInterface $root        root node | 
            
                                                                                                            
                            
            
                                    
            
            
                | 42 |  |  |      * @param string        $targetClass callback will be applied only to nodes that are instances of $targetClass or inherited classes | 
            
                                                                                                            
                            
            
                                    
            
            
                | 43 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 44 |  |  |     public static function applyCallback(callable $callback, NodeInterface $root, $targetClass = ChildNodeInterface::class) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 45 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 46 |  |  |         $processed = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 47 |  |  |         $f = function (ChildNodeInterface $targetNode) use ($callback, $targetClass, &$f, &$processed) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 48 |  |  |             if (in_array($targetNode, $processed, true)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 49 |  |  |                 return; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 50 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 51 |  |  |             $nodes = $targetNode instanceof ParentNodeInterface | 
            
                                                                                                            
                            
            
                                    
            
            
                | 52 |  |  |                 ? $targetNode->getChildrenRecursive()->toArray() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 53 |  |  |                 : []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 54 |  |  |             $nodes[] = $targetNode; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 55 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 56 |  |  |             /** @var NodeInterface $node */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 57 |  |  |             foreach ($nodes as $node) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 58 |  |  |                 $node instanceof $targetClass && call_user_func($callback, $node); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 59 |  |  |                 $node instanceof ParentNodeInterface && $node->children()->onItemAdd($f); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 60 |  |  |                 $processed[] = $node; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 61 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 62 |  |  |         }; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 63 |  |  |         $f($root); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 64 |  |  |     } | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 65 |  |  | } | 
            
                                                        
            
                                    
            
            
                | 66 |  |  |  |