PHP Dynamic and Recursive Menu System
When building the dynamic menu at my previous job, for our CMS, we had one class that dynamicly builds/prints the menu based on the menu object.
View output example of the code below
Since you're kind of new, I don't suggest making any overkill menu, but try to keep it as simple as possible.
I suggest making a class for the menu, where you send/store the menu array. This way you can make other objects unlock/lock different menu objects, or even send a sub-menu to that menu class (depending on how complex you want to make it).
This allows you to dynamicly build the menu as you run through the system code, and print the menu when your code is finished running. That way you can put the user based menu items in each section of the code, which handles that part.
For example, when running the system, make a function/method that checks the user access and for simple solutions, have hard-coded arrays with menu objects for each user access, or if going hardcore, build the menu arrays dynamicly. That's up to you.
<?php
// Let's create the child menu array for the "Home" menu structure
$home[] = array('TITLE' => 'Home 1',
'URL' => '/home-1-url-here',
'CSS_CLASS' => 'sub-menu',
'CHILDREN' => $home1Child);
$home[] = array('TITLE' => 'Home 2',
'URL' => '/home-2-url-here',
'CSS_CLASS' => 'sub-menu');
// Now we create the whole home array, with the children
$homeMenu = array('CSS_CLASS' => 'top-css-class',
'TITLE' => 'Home',
// If the top menu item is just a link, specify an URL
'URL' => '',
// Or if it has children pass them on
'CHILDREN' => $home);
// Let's create the child menu array for the "Gallery" menu structure
$gallery[] = array('TITLE' => 'Gallery 1',
'URL' => '/gallery-1-url-here',
'CSS_CLASS' => 'sub-menu');
$gallery2Child[] = array('TITLE' => 'Gallery 2.1',
'URL' => '/gallery-2.1-url-here',
'CSS_CLASS' => 'sub-menu-child');
$gallery2Child[] = array('TITLE' => 'Gallery 2.2',
'URL' => '/gallery-2.2-url-here',
'CSS_CLASS' => 'sub-menu-child');
$gallery[] = array('TITLE' => 'Gallery 2',
'URL' => '/gallery-2-url-here',
'CSS_CLASS' => 'sub-menu',
'CHILDREN' => $gallery2Child);
// Now we create the whole gallery array, with the children
$galleryMenu = array('CSS_CLASS' => 'top-css-class',
'TITLE' => 'Gallery',
// If the top menu item is just a link, specify an URL
'URL' => '',
// Or if it has children pass them on
'CHILDREN' => $gallery);
$menu = new menu;
// Store the menu items we want in the menu
$menu->storeItem($homeMenu);
$menu->storeItem($galleryMenu);
// Print the menu
echo $menu->buildMenu();
If you want to make sub-menus aswell, make the menu class work recursively.
class menu {
private $mainMenuClass = 'main-menu-class';
private $parentClass = 'parent-menu-class';
private $menu;
public function storeItem($menuItem, $parentClass = '') { // If no $parentClass is specified, pick the default one
// This stores the menu in an array
$this->menu[] = $menuItem;
}
public function buildMenu() {
// Let's break down the menu array, and start building it
$html = '<ul class="'. $this->mainMenuClass .'">'. PHP_EOL;
foreach($this->menu as $parentClass => $item) {
$html .= '<li class="'. $item['CSS_CLASS'] .'"><a href="'. $item['URL'] .'">'. $item['TITLE'] .'</a>'. PHP_EOL;
// Check if it's a recursive sub-menu (with children)
// Now we send the children array to the buildChildrenItems() method
$html .= $this->buildChildrenItems($item['CHILDREN']);
$html .= '</li>'. PHP_EOL;
}
$html .= '</ul>'. PHP_EOL;
return $html;
}
public function buildChildrenItems($menuSection) {
// Put the recursive logics here so we can keep looping
$html = '<ul class="'. $this->parentClass .'">'. PHP_EOL;
foreach($menuSection as $item) {
$html .= '<li class="'. $item['CSS_CLASS'] .'"><a href="'. $item['URL'] .'">'. $item['TITLE'] .'</a>'. PHP_EOL;
// Now here is where the recursive magic happends
// If the child item has even more children, call this method once again for those children
$html .= ( isset($item['CHILDREN']) && is_array($item['CHILDREN']) ) ? $this->buildChildrenItems($item['CHILDREN']) : '';
$html .= '</li>'. PHP_EOL;
}
$html .= '</ul>'. PHP_EOL;
return $html;
}
}
?>
From here you just design the menu as you want, using the CSS classes.
If you want to make it recursive (with dynamic sub-menus), then simply make the recursive logics before calling the buildChildrenItems() method. This is included in the code example above.
For more complex recursive menus, try these arrays.
$home1Child[] = array('TITLE' => 'Home 1.1',
'URL' => '/home-1.1-url-here',
'CSS_CLASS' => 'sub-menu-child');
$home121Child[] = array('TITLE' => 'Home 1.2.1',
'URL' => '/home-1.2.1-url-here',
'CSS_CLASS' => 'sub-menu-child');
$home121Child[] = array('TITLE' => 'Home 1.2.2',
'URL' => '/home-1.2.2-url-here',
'CSS_CLASS' => 'sub-menu-child');
$home1Child[] = array('TITLE' => 'Home 1.2',
'URL' => '/home-1.2-url-here',
'CSS_CLASS' => 'sub-menu-child',
'CHILDREN' => $home121Child);
$home1Child[] = array('TITLE' => 'Home 1.3',
'URL' => '/home-1.3-url-here',
'CSS_CLASS' => 'sub-menu-child');
$home[] = array('TITLE' => 'Home 1',
'URL' => '/home-1-url-here',
'CSS_CLASS' => 'sub-menu',
'CHILDREN' => $home1Child);
$home[] = array('TITLE' => 'Home 2',
'URL' => '/home-2-url-here',
'CSS_CLASS' => 'sub-menu');
$home[] = array('TITLE' => 'Home 3',
'URL' => '/home-3-url-here',
'CSS_CLASS' => 'sub-menu');
// Now we create the whole home array, with the children
$homeMenu = array('CSS_CLASS' => 'top-css-class',
'TITLE' => 'Home',
// If the top menu item is just a link, specify an URL
'URL' => '',
// Or if it has children pass them on
'CHILDREN' => $home);
// Let's create the child menu array for the "Gallery" menu structure
$gallery[] = array('TITLE' => 'Gallery 1',
'URL' => '/gallery-1-url-here',
'CSS_CLASS' => 'sub-menu');
$gallery2Child[] = array('TITLE' => 'Gallery 2.1',
'URL' => '/gallery-2.1-url-here',
'CSS_CLASS' => 'sub-menu-child');
$gallery2Child[] = array('TITLE' => 'Gallery 2.2',
'URL' => '/gallery-2.2-url-here',
'CSS_CLASS' => 'sub-menu-child');
$gallery[] = array('TITLE' => 'Gallery 2',
'URL' => '/gallery-2-url-here',
'CSS_CLASS' => 'sub-menu',
'CHILDREN' => $gallery2Child);
// Now we create the whole gallery array, with the children
$galleryMenu = array('CSS_CLASS' => 'top-css-class',
'TITLE' => 'Gallery',
// If the top menu item is just a link, specify an URL
'URL' => '',
// Or if it has children pass them on
'CHILDREN' => $gallery);
View output example of the code above
Finally, in the different classes for example, let's say the Gallery. Create the gallery menu array, check what kind of access the user has, and build it properly. Then you send the gallery menu array to the menu class, as shown above.
This concept is also good for future expansions, so when adding a new class/section on the website, let's say a guestbook. All the menu logics are built in that class and just sent to the dynamic menu class which builds it.
I do not recommend putting all the menu logics inside one big menu file, but as you run the system code, process each section and build the menu object as you go.
Hope this helps you on your way!
PS. If you have alot of user access types, and want to keep a clean code, put the menu arrays for each user access in seperate php files. (user_type_member.php or user_type_admin.php).
In the php code, where the arrays are written, just make a user type check, and call the according php file to load the array for that user.
switch($userType) {
default:
case 'visitor': include('user_type_visitor.php'); break;
case 'member': include('user_type_member.php'); break;
case 'admin': include('user_type_admin.php'); break;
}
Regards,
Andreas.
You're doing this backwards. Forget about the design patterns for awhile.
Just build your calculator program. Build it from scratch, and just design it however it is intuitive to you. Think about it for a few minutes, come up with a few ideas, then roll with it, start to finish.
While you are trying to implement your calculator, you might not design it right the first time and will have to restructure it now and then as you learn more about what's involved in your design. This is the process of learning, and this will teach you about how you've structured your code to attack the problem at hand.
Then, after you've done that, then take a look at the design patterns described in the
GoF book, and see what patterns most closely describe how you ended up designing your calculator. Now you know what those patterns are used for, and now you'll know how to choose what pattern makes sense to apply when.
Design patterns are not building blocks, they are names for common structural paradigms, to improve communication with other developers.
Best Answer
First, add the related web address to your config file:
Now, change the code in your Spider.php that it checks all .php files in that config directory, loads them all dynamically one-by-one, and store the "$conf" content in a dictionary where the url is used as a key. Then it should be easy to replace your "if-else" list by a simple loop over that dictionary.