The code is working rightly with the error:
Notice: Use of undefined constant bigdata - assumed 'bigdata' in
C:\xampp\htdocs\dynamic_menu\index.php on line 4
Code as followed:
//Set the database connection
($GLOBALS["___mysqli_ston"] = mysqli_connect('localhost', 'root', 'chethan'));
((bool)mysqli_query($GLOBALS["___mysqli_ston"], "USE " . 'bigdata'));
//select all rows from the main_menu table
$result = mysqli_query($GLOBALS["___mysqli_ston"], "select id,title,parentid,link from main_menu");
//create a multidimensional array to hold a list of menu and parent menu
$menu = array(
'menus' => array(),
'parent_menus' => array()
);
//build the array lists with data from the menu table
while ($row = mysqli_fetch_assoc($result)) {
//creates entry into menus array with current menu id ie. $menus['menus'][1]
$menu['menus'][$row['id']] = $row;
//creates entry into parent_menus array. parent_menus array contains a list of all menus with children
$menu['parent_menus'][$row['parentid']][] = $row['id'];
}
// Create the main function to build milti-level menu. It is a recursive function.
function buildMenu($parent, $menu) {
$html = "";
if (isset($menu['parent_menus'][$parent])) {
$html .= "<ul>";
foreach ($menu['parent_menus'][$parent] as $menu_id) {
if (!isset($menu['parent_menus'][$menu_id])) {
$html .= "<li><a href='" . $menu['menus'][$menu_id]['link'] . "'>" . $menu['menus'][$menu_id]['title'] . "</a></li>";
}
if (isset($menu['parent_menus'][$menu_id])) {
$html .= "<li><a href='" . $menu['menus'][$menu_id]['link'] . "'>" . $menu['menus'][$menu_id]['title'] . "</a>";
$html .= buildMenu($menu_id, $menu);
$html .= "</li>";
}
}
$html .= "</ul>";
}
return $html;
}
select database like this
mysqli_select_db($GLOBALS["___mysqli_ston"], 'bigdata');
insted of this
((bool)mysqli_query($GLOBALS["___mysqli_ston"], "USE " . 'bigdata'));
Related
I've made a recursive function to display the menu as a tree (each domain to have sub domains, and so on). The code works as is with a database, but I want to make it MVC to include it into my Codeigniter project.
I've tried splitting everything related to the database into the model, and so on... but doesn't work. You can see below the raw code, maybe someone can guide me how to change it to the MVC model. Thanks!!
<?php
$result = mysql_query("select id_domeniu, nume_domeniu, parent from domenii");
$menu = array(
'menus' => array(),
'parent_menus' => array()
);
while ($row = mysql_fetch_assoc($result)) {
//creates entry into menus array with current menu id ie. $menus['menus'][1]
$menu['menus'][$row['id_domeniu']] = $row;
//creates entry into parent_menus array. parent_menus array contains a list of all menus with children
$menu['parent_menus'][$row['parent']][] = $row['id_domeniu'];
}
function buildMenu($parent, $menu) {
$html = "";
if (isset($menu['parent_menus'][$parent])) {
$html .= "<ul>";
foreach ($menu['parent_menus'][$parent] as $menu_id) {
if (!isset($menu['parent_menus'][$menu_id])) {
$html .= "<li><a href='#'>" . $menu['menus'][$menu_id]['nume_domeniu'] . "</a></li>";
}
if (isset($menu['parent_menus'][$menu_id])) {
$html .= "<li><a href='#'>" . $menu['menus'][$menu_id]['nume_domeniu'] . "</a>";
$html .= buildMenu($menu_id, $menu);
$html .= "</li>";
}
}
$html .= "</ul>";
}
return $html;
}
?>
<!doctype html>
<html lang=''>
<head>
<meta charset='utf-8'>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles.css">
<script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>
<script src="script.js"></script>
<title>Test</title>
</head>
<body>
<div id='cssmenu'>
<?php echo buildMenu(0, $menu);; ?>
</div>
</body>
<html>
My attempt:
Model:
<?php
class New_menu_model extends CI_Model {
function get_domains() {
$result = $this->db->get ( 'domenii' );
return $result;
$menu = array(
'menus' => array(),
'parent_menus' => array()
);
while ($row = mysql_fetch_assoc($result)) {
//creates entry into menus array with current menu id ie. $menus['menus'][1]
$menu['menus'][$row['id_domeniu']] = $row;
//creates entry into parent_menus array. parent_menus array contains a list of all menus with children
$menu['parent_menus'][$row['parent']][] = $row['id_domeniu'];
}
}
function buildMenu($parent, $menu) {
$html = "";
if (isset($menu['parent_menus'][$parent])) {
$html .= "<ul>";
foreach ($menu['parent_menus'][$parent] as $menu_id) {
if (!isset($menu['parent_menus'][$menu_id])) {
$html .= "<li><a href='#'>" . $menu['menus'][$menu_id]['nume_domeniu'] . "</a></li>";
}
if (isset($menu['parent_menus'][$menu_id])) {
$html .= "<li><a href='#'>" . $menu['menus'][$menu_id]['nume_domeniu'] . "</a>";
$html .= buildMenu($menu_id, $menu);
$html .= "</li>";
}
}
$html .= "</ul>";
}
return $html;
}
}
?>
Controller:
function afisare_domenii_tree() {
$this->load->model ( 'new_menu_model' );
$data['domains'] = $this->new_menu_model->buildMenu ();
$this->load->view('new_menu', $data);
}
View (using a bootstrap template):
<?php echo buildMenu(0, $menu);?>
function get_domains() {
$result = $this->db->get ( 'domenii' );
return $result;
You already returned from the function above, the code after it will not execute. This should have been more like
function get_domains() {
$result = $this->db->get ( 'domenii' );
$menu = array(
'menus' => array(),
'parent_menus' => array()
);
while ($row = mysql_fetch_assoc($result)) {
//creates entry into menus array with current menu id ie. $menus['menus'][1]
$menu['menus'][$row['id_domeniu']] = $row;
//creates entry into parent_menus array. parent_menus array contains a list of all menus with children
$menu['parent_menus'][$row['parent']][] = $row['id_domeniu'];
}
return $menu;
}
I have updated your model. You cannot use mysql_ functions - Instead take a look at Codeigniter's Query Builder functions here ... http://www.codeigniter.com/userguide3/database/query_builder.html
<?php
class New_menu_model extends CI_Model {
function get_domains() {
$result = $this->db->get ( 'domenii' );
$menu = array(
'menus' => array(),
'parent_menus' => array()
);
foreach($result->result_array() as $row)
{
//creates entry into menus array with current menu id ie. $menus['menus'][1]
$menu['menus'][$row['id_domeniu']] = $row;
//creates entry into parent_menus array. parent_menus array contains a list of all menus with children
$menu['parent_menus'][$row['parent']][] = $row['id_domeniu'];
}
return $menu;
}
function buildMenu($parent, $menu) {
$html = "";
if (isset($menu['parent_menus'][$parent])) {
$html .= "<ul>";
foreach ($menu['parent_menus'][$parent] as $menu_id) {
if (!isset($menu['parent_menus'][$menu_id])) {
$html .= "<li><a href='#'>" . $menu['menus'][$menu_id]['nume_domeniu'] . "</a></li>";
}
if (isset($menu['parent_menus'][$menu_id])) {
$html .= "<li><a href='#'>" . $menu['menus'][$menu_id]['nume_domeniu'] . "</a>";
$html .= $this->buildMenu($menu_id, $menu);
$html .= "</li>";
}
}
$html .= "</ul>";
}
return $html;
}
}
?>
Needed Navigation Html
Home
Pages
About
Services
Products
Contact
FAQs
Sitemap
Privacy Policy
Column Layouts
1 Column
2 Column (Left Sidebar)
2 Column (Right Sidebar)
3 Column
4 Column
I want to use php arrays and foreach loops to output the needed html.
The php code I have thus far is:
<?php
$data = array("navigation");
$data['navigation']['Home'] = base_url();
$data['navigation']['Pages'] = base_url('pages');
$data['navigation']['Pages']['About'] = base_url('pages/about');
echo '<ul>';
foreach($data as $nav) {
foreach($nav as $subNavKey => $subNavHref) {
echo "<li><a href='$subNavHref'>$subNavKey</a>";
}
}
echo '</ul>';
?>
I was thinking I would need three foreach loops nested but php warnings/errors are generated when the third loop is reached on lines such as:
$data['navigation']['Home'] = base_url();
$data['navigation']['Pages'] = base_url('pages');
I'm not quite sure how to test for 3rd level depths such as:
$data['navigation']['Pages']['About'] = base_url('pages/about');
Also, outputting the needed li and ul tags in the proper positions has given me trouble aswell.
Use recursion
$data['navigation']['Home'] = base_url();
$data['navigation']['Pages'] = base_url('pages');
$data['navigation']['Pages']['About'] = base_url('pages/about');
$data['navigation']['Pages']['About']['Team'] = base_url('pages/team');
$data['navigation']['Pages']['About']['Team']['Nate'] = base_url('pages/nate');
echo "<ul>"
print_list($data);
echo "</ul>"
function print_list($menu) {
foreach($menu as $key=>$item) {
echo "<li>";
if(is_array($item)) {
echo "<ul>";
print_list($item);
echo "</ul>";
} else {
echo "<a href='{$val}'>$key</a>";
}
echo "</li>";
}
}
<?php
function nav($data) {
$html = '<ul>';
foreach ($data as $k => $v) {
if (is_array($v)) {
$html .= "<li>$k" . nav($v) . "</li>";
}
else {
$html .= "<li><a href='$k'>$v</a>";
}
}
$html .= '</ul>';
return $html;
}
echo nav($data);
A recursive function can get the job done:
$items = array(
"Home",
"Pages" => array(
"About",
"Services",
"Products",
"Contact",
"FAQs",
"Sitemap",
"Privacy Policy",
"Column Layouts" => array(
"1 Column",
"2 Column (Left Sidebar)",
"2 Column (Right Sidebar)",
"3 Column",
"4 Column"
)
)
);
function getMenu($array) {
foreach($array as $key => $value) {
if(is_array($value)) {
echo "<li>" . $key . "</li>";
echo "<ul>";
getMenu($value);
echo "</ul>";
} else {
echo "<li>" . $value . "</li>";
}
}
}
echo "<ul>";
getMenu($items);
echo "</ul>";
Output:
You should use a recursive function, for example (Working Demo):
function makeMenu($array)
{
$menu = '';
foreach($array as $key => $value) {
if(is_array($value)) {
$menu .= '<li>' . $key . '<ul>' . makeMenu($value) . '</ul></li>';
}
else {
$menu .= "<li><a href='". $value ."'>" . $value ."</a></li>";
}
}
return $menu;
}
Then call it like:
$data = array(
"Home",
"Pages" => array("About", "Services"),
"Column Layouts" => array("1 Column", "2 Column (Left Sidebar)")
);
echo '<ul>' . makeMenu($data) . '</ul>';
$menu = array(
0 =>'top',
1 =>'photography',
2 =>'about'
);
<?php
function main_menu ($menu) {
$return = '<div class="menu_entry">' . PHP_EOL .'';
foreach( $menu as $key => $value)
{
$return .= '<a class="menu" href="index.php#' . $menu[$key] . '">' . $menu[$key] . '</a>' . PHP_EOL .'';
}
$return .= '</div>';
return $return;
}
?>
<?php echo main_menu($menu[1]); ?>
What i basically want to do is to pass a specific array value when i'm echoing out the menu.
I'm building a single page website with anchors and i want to pass value's so i can echo out the "top"-link.
I'm stuck at the point on how to pass the $key value trough the function.
**edit: I'm trying to print specific links. I want a function that is able to print out an link but i want to specify the link to print via the function argument.
for example:
<?php echo main_menu($key = '0'); ?>
result:
prints url: top
<?php echo main_menu($key = '2'); ?>
result:
prints url: photography
**
(A lack of jargon makes it a bit harder to explain and even harder to google.
I got my books in front of me but this is taking a lot more time than it should.)
You either need to pass the entire array and loop, or pass a single array item and not loop:
Single Item:
function main_menu ($menu) {
$return = '<div class="menu_entry">' . PHP_EOL .'';
$return .= '<a class="menu" href="index.php#' . $menu . '">' . $menu . '</a>' . PHP_EOL .'';
$return .= '</div>';
return $return;
}
echo main_menu($menu[1]);
Entire Array:
function main_menu ($menu) {
$return = '<div class="menu_entry">' . PHP_EOL .'';
foreach($menu as $value) {
$return .= '<a class="menu" href="index.php#' . $value . '">' . $value . '</a>' . PHP_EOL .'';
}
$return .= '</div>';
return $return;
}
echo main_menu($menu);
You don't need $menu[$key] just use the $value.
Should you not just be using $value inside your loop? And passing the entire array rather than one item of the $menu array?
$menu = array(
0 =>'top',
1 =>'photography',
2 =>'about'
);
<?php
function main_menu ($menu) {
$return = '<div class="menu_entry">' . PHP_EOL .'';
foreach( $menu as $key => $value)
{
$return .= '<a class="menu" href="index.php#' . $value . '">' . $value . '</a>' . PHP_EOL .'';
}
$return .= '</div>';
return $return;
}
?>
<?php echo main_menu($menu); ?>
Try:
echo main_menu($menu); // You will get your links printed
Instead of
echo main_menu($menu[1]); // In this case error is occured like : **Invalid argument supplied for foreach**
NOTE: You can use $value instead of $menu[$key]
So I'm trying to create a dynamic navigation bar that is built through menu items stored in a database.
Each menu item is assigned a parent_id, if that id is 0, that item is a parent; if that id is a value above 0, then that menu item is the child of another menu item. (Imagine hovering over a navigation menu item and getting a drop down of children items)
The following function is what builds the multi-dimensional array from the records in the database.
function build_menu($menu_id){
$mysqli = new mysqli("localhost", "user", "password", "db");
if($mysqli->connect_errno){
echo "Failed to connect to MySQL: " . $mysqli->connect_errno;
}
$stmt = $mysqli->prepare("SELECT `id`, `name`, `order`, `parent_id`, `path` FROM menu_items WHERE `group_id` = ? ORDER BY `order` ASC");
$menu_id = intval($mysqli->real_escape_string($menu_id));
$stmt->bind_param('i', $menu_id);
if($stmt->execute()){
$results = resultToArray($stmt->get_result());
$parents = array();
$children = array();
$menu = array();
for($i=0; $i<count($results); $i++){
if($results[$i]['parent_id'] === 0){
$parents[] = $results[$i];
} else {
$children[] = $results[$i];
}
}
for($i=0; $i<count($parents); $i++){
$menu[$i] = $parents[$i];
for($j=0; $j<count($children); $j++){
if($children[$j]['parent_id'] === $parents[$i]['id']){
$menu[$i][$j] = $children[$j];
}
}
}
return($menu);
} else {
echo "Failed to execute statement: " . $stmt->errno . ": " . $stmt->error;
}
$mysqli->close();
return(0);
}
This is the function that takes that array and turns it into HTML code to be used as the navigation bar.
function get_menu($menu_id) {
if(build_menu($menu_id)){
$menu = build_menu($menu_id);
$menu_html = '<ul>';
for($i=0; $i<count($menu); $i++){
$menu_item_path = ($menu[$i]['path'] != NULL ? $menu[$i]['path'] : '#');
$menu_html .= '<li>' . $menu[$i]['name'] . '';
if(count($menu[$i])>0){
$menu_html .= '<ul>';
for($j=0; $j<count($menu[$i]); $j++){
if(isset($menu[$i][$j])){
$menu_html .= '<li>' . $menu[$i][$j]['name'] . '</li>';
}
}
$menu_html .= '</ul>';
}
$menu_html .= '</li>';
}
$menu_html .= '</ul>';
return($menu_html);
}
}
I presumed that if(count($menu[$i])>0) would count the array inside the selected element, but for some reason, it counts the keys and therefore always true.
I know this is a pretty long question, I do appreciate those of you that have read this far. If you can help me figure out a way to see if a menu item has children items, that would be great.
use array_filter to count only the items in array not empty or null
Process of generating HTML menu can be a lot easier than your example.
function generateMenu(array $menu, $parentId = 0) {
if (!isset($menu[$parentId])) {
return;
}
$output = '<ul>';
foreach ($menu[$parentId] as $record) {
$output .= '<li>';
$output .= '' . $record['title'] . '';
$output .= generateMenu($menu, $record['id']);
$output .= '</li>';
}
$output .= '</ul>';
return $output;
}
echo generateMenu($menu);
Above code would output HTML like:
x First level #1
o Second level #8
x First level #2
o Second level #4
- Third level #6
- Third level #7
o Second level #5
x First level #3
demo
But for that to work, you must fix your build_menu() function, to return array like this, which is very easy, just create one array $menu and fill it like $menu[$row['parent_id']][] = $row;, where $row is record row fetched from database.
I know there are similar questions here and I have read some of the posts and answers, experimented with some of them, but whether it is my limited knowledge of PHP or the peculiarity of my case, I need to ask this.
I am building a dictionary (id, english, bulgarian, theme_id) and would like to group the search results according to theme_id. I am using ORDER BY theme_id, id in my query but I end up displaying the theme with each of the results, while I would like to categorize them as follows:
THEME 1
- result 1
- result 2
THEME 2
- result 3
- result 4
.....
Here is the relevant part of my code:
while($row = mysql_fetch_array($result)) {
//$id = $row['id'];
$english = $row['english'];
$bulgarian = $row['bulgarian'];
$theme_id = $row['theme_id'];
$theme_name = "theme_".$lang;
$theme_query= mysql_query("SELECT theme_id,".$theme_name." FROM ".DICTIONARY_THEMES." WHERE theme_id = ".$theme_id."");
$theme_row = mysql_fetch_array($theme_query);
$theme = $theme_row[$theme_name];
if($source == "english") {
foreach($keywords as $keyword) {
$english = preg_replace("|($keyword)|Ui", "<span style=\"color:#780223\">".$keyword."</span>", $english);
}
$print .= "<li class=\"results-row\">".$theme.": ".$english." = ".$bulgarian."</li>";
}
elseif($source == "bulgarian") {
foreach($keywords as $keyword) {
$bulgarian = preg_replace("|($keyword)|Ui", "<span style=\"color:#780223;\">".$keyword."</span>", $bulgarian);
}
$print .= "<li class=\"results-row\">".$theme.": ".$bulgarian." = ".$english."</li>";
}
}//end while
EDIT: SOLVED, a friend has helped improve my code.
while($row = mysql_fetch_array($result)) {
$english = $row['english'];
$bulgarian = $row['bulgarian'];
$theme_id = $row['theme_id'];
$theme_name = "theme_".$lang;
$theme_query= mysql_query("SELECT theme_id,".$theme_name." FROM ".DICTIONARY_THEMES." WHERE theme_id = ".$theme_id."");
$theme_row = mysql_fetch_array($theme_query);
$theme = $theme_row[$theme_name];
// add all results to an array
$results[] = array(
'english' => $english,
'bulgarian' => $bulgarian,
'theme' => $theme
);
}//end while
$theme = null;
foreach ($results as $result) {
if ($theme != $result['theme']) {
$theme = $result['theme'];
$print .= "<h3>" . $result['theme'] . "</h3>";
}
if ($source == "english") {
foreach ($keywords as $keyword) {
$result['english'] = preg_replace("|($keyword)|Ui", "<span style=\"color:#780223\">" . $keyword . "</span>", $result['english']);
}
$print .= "<li class=\"results-row\">" . $result['english'] . " = " . $result['bulgarian'] . "</li>";
} elseif ($source == "bulgarian") {
foreach ($keywords as $keyword) {
$result['bulgarian'] = preg_replace("|($keyword)|Ui", "<span style=\"color:#780223;\">" . $keyword . "</span>", $result['bulgarian']);
}
$print .= "<li class=\"results-row\">" . $result['bulgarian'] . " = " . $result['english'] . "</li>";
}
}
Based on your code, you should first add all items to an array and afterwards print that array in a separate function/block.
Right after your second MySQL query, put something like
$output[$theme_id] = mysql_fetch_array( $theme_query );
and move all the following code out of the outer result-while-loop (while($row = mysql_fetch_array($result))).
But in fact I would try to put a MySQL query together, to have an ordered, grouped result with all the selected themes in all languages and without querying the database inside a loop.
Or you use something existing, for example this singleton Lexicon class.