GetSimple Support Forum

Full Version: Function menu_data not returning ALL menu items
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I created a component to display the menu_data() array. I have three pages defined, all are on the menu and none are private. Also, I'm using PRETTYURLS. When I call it without params, it returns one array element for the index file. If I call it with a slug, it returns that slug's page info (as advertised), but its not returning ALL menu items.

Code:
if ($PRETTYURLS == '1') {
                        if ($parent != '') {$parent = $parent."/"; }
                        if ($slug == 'index' ) { $slug = ''; }
                        $url = $SITEURL . @$parent . $slug;
                    } else {
                        $url = $SITEURL .'index.php?id='.$slug;
                    }

                    $specific = array("slug"=>$slug,"url"=>$url,"parent_slug"=>$parent,"title"=>$title,"menu_priority"=>$pri,"menu_text"=>$text);

                    if ($id == $slug) {
                        return $specific; exit;
                    } else {
                        $menu_extract[] = $specific;
                    }

I suspect its in this area, perhaps something to do with setting the slug to '' when the slug = 'index'... but not sure. Could someone take a look? Thanks.


Update and Fix: I believe a suitable fix is;

Code:
// if ($slug == 'index' ) { $slug = ''; }
$url = $SITEURL . @$parent . (($slug == 'index') ? '' : $slug);

This works for me.
bnowell,

This function is still a work in progress. Only a preliminary version is in 1.5. Below is the revised code.. replace your's with it and let me know if you get a better result.

Code:
function menu_data($id = null) {
        $menu_extract = '';
        global $PRETTYURLS;
        global $SITEURL;
        
        $path = "data/pages";
        $dir_handle = @opendir($path) or die("Unable to open $path");
        $filenames = array();
        while ($filename = readdir($dir_handle)) {
            $filenames[] = $filename;
        }
        
        $count="0";
        $pagesArray = array();
        if (count($filenames) != 0) {
            foreach ($filenames as $file) {
                if ($file == "." || $file == ".." || is_dir("data/pages/".$file) || $file == ".htaccess"  ) {
                    // not a page data file
                } else {
                    $thisfile = @file_get_contents('data/pages/'.$file);
                    $data = simplexml_load_string($thisfile);
                    if ($data->private != 'Y') {
                        $pagesArray[$count]['menuStatus'] = $data->menuStatus;
                        $pagesArray[$count]['menuOrder'] = $data->menuOrder;
                        $pagesArray[$count]['menu'] = $data->menu;
                        $pagesArray[$count]['parent'] = $data->parent;
                        $pagesArray[$count]['title'] = $data->title;
                        $pagesArray[$count]['url'] = $data->url;
                        $pagesArray[$count]['private'] = $data->private;
                        $count++;
                    }
                }
            }
        }
        
        $pagesSorted = subval_sort($pagesArray,'menuOrder');
        if (count($pagesSorted) != 0) {
            $count = 0;
            foreach ($pagesSorted as $page) {
                    $text = (string)$page['menu'];
                    $pri = (string)$page['menuOrder'];
                    $parent = (string)$page['parent'];
                    $title = (string)$page['title'];
                    $slug = (string)$page['url'];
                    $menuStatus = (string)$page['menuStatus'];
                    $private = (string)$page['private'];
                    
                    if ($PRETTYURLS == '1') {
                        if ($parent != '') {$parent = tsl($parent); }
                        if ($slug == 'index' ) { $slug = ''; }
                        $url = $SITEURL . @$parent . $slug;
                    } else {
                        $url = $SITEURL .'index.php?id='.$slug;
                    }
                    
                    $specific = array("slug"=>$slug,"url"=>$url,"parent_slug"=>$parent,"title"=>$title,"menu_priority"=>$pri,"menu_text"=>$text,"menu_status"=>$menuStatus,"private"=>$private);
                    
                    if ($id == $slug) {
                        return $specific;
                        exit;
                    } else {
                        $menu_extract[] = $specific;
                    }
                
            }
            return $menu_extract;
        }
        
        closedir($dir_handle);
    }
That function gives you every page, not only those that are enabled on the menu (but if menuStatus=='Y', then it is enabled). This should be sufficient for those of you who want to create special code to do multi-level menus.
I tried your new function and it still only gives me back the first menu option (index page). Perhaps the configuration of my PHP is treating NULL as a '' blank... I've not heard of that, but you never know.

The code part that sets the slug to '' AND further down when it checks $id==$slug, its bailing at that point, because $slug was set to ''. But how $id=Null evaluates to $id='', escapes me. Does that make sense?
any chance of getting this returned as an XML object as an option.
This would allow us to do some XPATH queries on the data.

Code:
// returns menu with submenus
// submenu items are children of menu items.
$data=menu_data();
$components = subval_sort($data->xpath("//*[menuStatus='Y']"),'menuOrder');
foreach ($components as $menu){
   echo "<li>".$menu->url."</li>";
   $submenus= $data->xpath("//*[parent='".$menu->url."']");
   if (count($submenus) != 0) {
     echo "<ul>";
     foreach ($submenus as $submenu){
       echo "<li class='submenu'>".$submenu->url."</li>";
     }
   echo "</ul>";
    }
}

M
n00dles101 are you using PRETTYURL's? You don't appear to be having any problems get back all your menu data from the menu_data function. I still needed to put my two-liner fix in to get back the ALL the items.
revised script working fine Chris.
Returning all pages...

M
bnowell, hhmm, it works for me just fine... I have 3 pages, and all gets returned with this code:

Code:
<?php
$data = menu_data();
print_r($data);
?>

http://cagintranet.com/images/gs/
Mike - if you want to change that function to allow an optional second param to return an XML object, just give me the revised code and I will replace the function... Thanks!
here's the undated function to allow XML
I've added in pubdate and changed the names to match what they are in pages XML files.



Code:
function menu_data($id = null,$xml=false) {
        $menu_extract = '';
        global $PRETTYURLS;
        global $SITEURL;
        
        $path = "data/pages";
        $dir_handle = @opendir($path) or die("Unable to open $path");
        $filenames = array();
        while ($filename = readdir($dir_handle)) {
            $filenames[] = $filename;
        }
        
        $count="0";
        $pagesArray = array();
        if (count($filenames) != 0) {
            foreach ($filenames as $file) {
                if ($file == "." || $file == ".." || is_dir("data/pages/".$file) || $file == ".htaccess"  ) {
                    // not a page data file
                } else {
                    $thisfile = @file_get_contents('data/pages/'.$file);
                    $data = simplexml_load_string($thisfile);
                    if ($data->private != 'Y') {
                        $pagesArray[$count]['menuStatus'] = $data->menuStatus;
                        $pagesArray[$count]['menuOrder'] = $data->menuOrder;
                        $pagesArray[$count]['menu'] = $data->menu;
                        $pagesArray[$count]['parent'] = $data->parent;
                        $pagesArray[$count]['title'] = $data->title;
                        $pagesArray[$count]['url'] = $data->url;
                        $pagesArray[$count]['private'] = $data->private;
                        $count++;
                    }
                }
            }
        }
        
        $pagesSorted = subval_sort($pagesArray,'menuOrder');
        if (count($pagesSorted) != 0) {
            $count = 0;
            if (!$xml){
            foreach ($pagesSorted as $page) {
                    $text = (string)$page['menu'];
                    $pri = (string)$page['menuOrder'];
                    $parent = (string)$page['parent'];
                    $title = (string)$page['title'];
                    $slug = (string)$page['url'];
                    $menuStatus = (string)$page['menuStatus'];
                    $private = (string)$page['private'];
                    
                    if ($PRETTYURLS == '1') {
                        if ($parent != '') {$parent = tsl($parent); }
                        if ($slug == 'index' ) { $slug = ''; }
                        $url = $SITEURL . @$parent . $slug;
                    } else {
                        $url = $SITEURL .'index.php?id='.$slug;
                    }
                    
                    $specific = array("slug"=>$slug,"url"=>$url,"parent_slug"=>$parent,"title"=>$title,"menu_priority"=>$pri,"menu_text"=>$text,"menu_status"=>$menuStatus,"private"=>$private);
                    
                    if ($id == $slug) {
                        return $specific;
                        exit;
                    } else {
                        $menu_extract[] = $specific;
                    }
                
            }
            return $menu_extract;
            } else {
            $xml = '<?xml version="1.0" encoding="UTF-8"?><channel>';    
            foreach ($pagesSorted as $page) {
                    $text = $page['menu'];
                    $pri = $page['menuOrder'];
                    $parent = $page['parent'];
                    $title = $page['title'];
                    $slug = $page['url'];
                    $pubdate = $page['pubDate'];
                    $menuStatus = $page['menuStatus'];
                    $private = $page['private'];
                    if ($PRETTYURLS == '1') {
                        if ($parent != '') {$parent = tsl($parent); }
                        if ($slug == 'index' ) { $slug = ''; }
                        $url = $SITEURL . @$parent . $slug;
                    } else {
                        $url = $SITEURL .'index.php?id='.$slug;
                    }
                    
                    $xml.="<item>";
                    $xml.="<slug><![CDATA[".$slug."]]></slug>";
                    $xml.="<pubdate><![CDATA[".$pubdate."]]></pubdate>";
                    $xml.="<url><![CDATA[".$url."]]></url>";
                    $xml.="<parent><![CDATA[".$parent."]]></parent>";
                    $xml.="<title><![CDATA[".$title."]]></title>";
                    $xml.="<menuOrder><![CDATA[".$pri."]]></menuOrder>";
                    $xml.="<menu><![CDATA[".$text."]]></menu>";
                    $xml.="<menuStatus><![CDATA[".$menuStatus."]]></menuStatus>";
                    $xml.="<private><![CDATA[".$private."]]></private>";
                    $xml.="</item>";
                    
            }
            $xml.="</channel>";
            return $xml;
            }
        }
        
        closedir($dir_handle);
    }

use in your template as:

Code:
$pages=simplexml_load_string(menu_data('',true));

// to get a list of menu items sorted by menuOrder
    $components = subval_sort($pages->xpath("//*[menuStatus='Y']"),'menuOrder');
        foreach ($components as $item){
       echo $item->menu;   // style as you require.
       }
Thanks Mike! Whats the purpose of having pubdate in there?
Chris,

I use it for my blogging component for sorting by date, but its not ideal as its the last updated date and not a published date. No harm having it there.


Mike.
Hi

I'm sorry, but I receive only top items of menu.
Can you upload working example ?
Thank!
I arrange code and i get a tree of menu.

But I don't understand : why when prettyurl is off SLUG is empty ??? Rolleyes
Problem solved http://get-simple.info/forum/viewtopic.php?pid=601#p601

I change function menu_data in theme.functions.php