PHP Classes

File: class.sb_menu_1.0.php

Recommend this page to a friend!
  Classes of JImmy Bo   SB PHP Menu Builder   class.sb_menu_1.0.php   Download  
File: class.sb_menu_1.0.php
Role: Class source
Content type: text/plain
Description: SB Menu - A PHP Class for Building Menus
Class: SB PHP Menu Builder
Create menus and store definitions in files
Author: By
Last change:
Date: 5 months ago
Size: 8,300 bytes
 

Contents

Class file image Download
<?php
/*
Name: SB Menu - A PHP Class for Building Menus
File: class.sb_menu.php
License: BSD 3-Clause License <https://opensource.org/licenses/BSD-3-Clause>
Description: A flatfile (look ma! no DB!) based php class to create/modify/save/load/display a menu tree.
Author: https://www.phpclasses.org/browse/author/144301.html
Homepage URL: https://www.phpclasses.org/package/12978-PHP-SB-Menu-A-PHP-Class-for-Building-Menus.html

PHP Version: 8+

Version: 1.0

Long Description:
    The SB Menu class is a PHP class that allows for the creation, modification, saving, loading, and display of a menu tree without the need for a database. This class is designed to be simple, efficient, and easily customizable. It uses a flatfile approach, meaning that the menu structure is stored in a text file rather than a database.
    'label' (user) and 'id' (generated) are default fields in the base class.

Methods:
    save($filename) - saves the menu tree to a file
    load($filename) - loads the menu tree from a file

    getNodeByField($field, $value) - returns a reference to the node with a field that matches a value
    applyCallbackToNode($id, $callback) - applies a callback to a node with a specific id
    applyCallbackToNodeByField($field, $value, $callback) - applies a callback to a node with a specific field that matches a value
   

Categories/Keywords:
        Menu Creation
        Tree Structure
        PHP Class
        Extended Class
        Flatfile Database
        Database-less
        No DB
        Menu Modification
        Menu Manipulation
        Callback Function
        Node Manipulation
        File Handling
        Dynamic Data
        Tree Root Node
        Child Nodes


    // include this file
    include_once("class.sb_menu_1.0.php");

    // example creation... (look at class.sb_menu.test.simple.php for extended class needed to render)
    class SimpleTree_Extended extends Tree { ... extended code ( render(), renderNode(), etc ) ... }

    // create extended class of Tree and throw in a render and renderNode to customize display based on dynamic data fields
    // we pass the name we want for the main root node. In the example, we skip rendering this root node.
    $menu = new SimpleTree_Extended(new TreeNode('Main Menu')); // .. or the extended class to seperate the render() method


    // now add some menus...
            // when menu is created, a root node is created and assigned to $menu->root. This is our main level.
            $last_menu = $menu->root->addChild(new TreeNode('Submenu 1'));
            $last_menu = $menu->root->addChild(new TreeNode('Submenu 2'));
                // another level
                $next_level = $last_menu->addChild(new TreeNode('Item 2.1'));
               
                // example adding more data for our extended class to use with a custom render() method
                $next_level->data['url'] = "https://www.google.com"; // handled in extended class render
                $next_level->data['target'] = "_blank"; // handled in extended class render

    // # use a callback to run some code on a specific node via its id (id and label are default fields in base class)
    $menu->applyCallbackToNode($s2_id, function($node) {
        $node->data['label'] = 'New Label';
        $new_submenu = new TreeNode('New Submenu');
        $node->addChild($new_submenu);
    });


    // example usage of applyCallbackToNodeByField($field, $value, $callback)
    // (this example changes the label of the node with label 'Submenu 1' to 'New Label')
    $menu->applyCallbackToNodeByField('label', 'Submenu 1', function($node) {
        $node->data['label'] = 'New Label';
    });


    // get the reference to the node by a field for modification. (only returns first match)
    // example usage of getNodeByField($key, $value)
    $s2 = $menu->getNodeByField('label', 'Submenu 2');
    $s2_id = $s2->data['id'];


    # save (ez) (make sure directory or file is writeable)
    $menu->save('menu-simple.txt');

    # load (pz)
    $menu2 = $menu->load('menu-simple.txt');


    // render (display the menu :: see example Tree extended class in class.sb_menu.test.simple.php )
    echo $menu->render('sbmenu'); // render defined in extended class

*/

class TreeNode {
    public
$data;
    public
$children = [];

    public function
__construct($data) {
       
#$this->data = $data;
       
$this->data['label'] = $data;
       
$this->data['id'] = uniqid();
    }

    public function
addChild(TreeNode $child) {
       
$this->children[] = $child;
       
// return a reference to the created object
       
return $child;
    }

}

class
Tree {
    public
$root;

    public function
__construct(TreeNode $root) {
       
$this->root = $root;
    }

    public function
render() {
       
// extended class for customizing rendering output
       
return '';
    }

    private function
renderNode(TreeNode $node, $depth)
    {
       
// extended class for customizing (see example in class.sb_menu.test.simple.php)
   
}

   
# a function to get a node by a field that matches a value
   
public function getNodeByField($field, $value) {
        return
$this->getNodeByFieldHelper($this->root, $field, $value);
    }

    private function
getNodeByFieldHelper($node, $field, $value) {
        if (!empty(
$node->data[$field]) && $node->data[$field] == $value) {
            return
$node;
        }
        foreach (
$node->children as $child) {
           
$result = $this->getNodeByFieldHelper($child, $field, $value);
            if (
$result !== null)
                return
$result;
        }
        return
null;
    }

   
/*
            // example usage of getNodeByField()
                $s2 = $menu->getNodeByField('label', 'Submenu 2');
                $s2_id = $s2->data['id'];
    */

    # a function to apply a callback to node with a specific id in the tree
   
public function applyCallbackToNode($id, $callback) {
       
$this->applyCallbackToNodeHelper($this->root, $id, $callback);
    }

    private function
applyCallbackToNodeHelper($node, $id, $callback) {
        if (
$node->data['id'] == $id) {
           
$callback($node);
        }
        foreach (
$node->children as $child) {
           
$this->applyCallbackToNodeHelper($child, $id, $callback);
        }
    }
   
/*
            // example usage of applyCallbackToNode()
                $menu->applyCallbackToNode('id', function($node) {
                    $node->data['label'] = 'New Label';
                });
    */

    # callback based off some other field...
   
public function applyCallbackToNodeByField($field, $value, $callback) {
       
$this->applyCallbackToNodeByFieldHelper($this->root, $field, $value, $callback);
    }

    private function
applyCallbackToNodeByFieldHelper($node, $field, $value, $callback) {
        if (
$node->data[$field] == $value) {
           
$callback($node);
        }
        foreach (
$node->children as $child) {
           
$this->applyCallbackToNodeByFieldHelper($child, $field, $value, $callback);
        }
    }

   
/*
            // example usage of applyCallbackToNodeByField()
                $menu->applyCallbackToNodeByField('label', 'Submenu 1', function($node) {
                    $node->data['label'] = 'New Label';
                });
    */

    # save
   
public function save($filename) {
       
$serializedData = serialize($this);
       
file_put_contents($filename, $serializedData);
    }

   
# load
   
public static function load($filename) {
       
$serializedData = file_get_contents($filename);
        if (
$serializedData !== false) {
           
$tree = unserialize($serializedData);
            if (
$tree instanceof Tree) {
                return
$tree;
            }
        }
        return
null;
    }


}



// # use a callback to run some code on a specific node via its id
// $menu->applyCallbackToNode($s2_id, function($node) {
// $node->data['label'] = 'New Label';
// $new_submenu = new TreeNode('New Submenu');
// $node->addChild($new_submenu);
// });



?>