Recursief menuscript uitbreiden

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Lead Mendix Developer

Heb jij passie voor software ontwikkeling en vind je het leuk om eindgebruikers snel te helpen door het realiseren van web en mobiele applicaties? Vind jij het leuk om junior ontwikkelaars te begeleiden en te enthousiasmeren door het delen van je kennis? Heb jij de ambitie om door te ontwikkelen naar een Full Stack ontwikkelaar? Dan is dit jouw topbaan! Met meer dan 100 bedrijven in verschillende product-marktcombinaties is geen dag hetzelfde bij VDL. Als Lead Low Code Developer ontwikkel je met Mendix nieuwe functionaliteiten voor bestaande applicaties. Applicaties waar eindgebruikers graag mee werken. Daarnaast zijn er tal van nieuwe

Bekijk vacature »

Low Code Developer

Heb jij passie voor software ontwikkeling en vind je het leuk om eindgebruikers snel te helpen door het realiseren van web en mobiele applicaties? Wil jij ervaring opdoen om van beginnend developer door te ontwikkelen naar een Full Stack ontwikkelaar? Dan is dit jouw topbaan! Met meer dan 100 bedrijven in verschillende product-marktcombinaties is geen dag hetzelfde bij VDL. Wat ga je doen? Als Low Code Developer ga je aan de slag om nieuwe applicaties te ontwikkelen op het gebied van web en mobiele applicaties die onder andere een Make To Order platform ondersteunen. Met behulp van bestaande bouwstenen ben

Bekijk vacature »

PHP developer fulltime

Als PHP developer bij Getnoticed werk je in een team met acht directe collega’s. Bij ons geen hiërarchie of weken beslissingstijd. Dit betekent korte lijnen en snel schakelen. Dat is ook wel nodig bij alle innovatieve projecten waar we tegelijkertijd aan werken, zoals Google Cloud Talent Solution. Jouw functie bij Getnoticed is voornamelijk het bedenken van oplossingen voor klanten, hen hierin adviseren en het schrijven van koppelingen. Je hebt hier veel vrijheid maar kunt altijd bij collega’s terecht om te sparren. In een week kun je zo voor 4 á 5 verschillende klanten werken. Dit houdt je werk afwisselend. Naast

Bekijk vacature »

Cloud Developer

Wil jij ontwikkelen in de Cloud, waarbij je ook te maken krijgt met Low Code platformen, bekende CRM-applicaties en, soms minder bekende, back-end applicaties? Ben je op zoek naar een rol binnen een jong team met een uitdagend applicatielandschap? Dan is dit jouw kans. Maak kennis met de meer dan 100 industriële bedrijven die vallen onder het familiebedrijf VDL Groep. Samen met het DevOps/agile team lever je een bijdrage aan onze verdere digitalisering. Daarbij ben je verantwoordelijk voor analyse, ontwerp, ontwikkeling, test en uitrollen van de services binnen ons Microsoft Azure platform. Wat ga je doen als Cloud Developer: Als

Bekijk vacature »

Front-end Mendix Developer

Front-end Mendix Developer Den Haag HBO/WO IT - software development Professional "PostNL wordt een logistiek tech bedrijf, waarbij data, technologie en een development cultuur een belangrijke rol spelen. Om de favoriete bezorger van Nederland te zijn en te blijven, zetten wij Mendix in om onze kritieke processen te ontwikkelen." Wat ga je doen? PostNL heeft de ambitie om uit te groeien tot het meest efficiënte en innovatieve logistieke post en e-commerce platform in de Benelux. Om die digitale transformatie tot een succes te maken, maken wij op een unieke manier gebruik van Mendix technologie. Wij zetten Mendix namelijk in voor

Bekijk vacature »

Parttime PHP Ontwikkelaar (medior)

Ben je op zoek naar een uitdagende baan met een bepalende rol binnen een organisatie en wil je direct impact hebben op de core business? Dan zoeken we jou! Wie zijn wij? Wat begon als kleine onderneming in een antikraak kantoor heeft zich de afgelopen 10 jaar ontwikkeld tot een professioneel bedrijf met een leidende positie in de markt. In de nichemarkt ‘busvervoer naar grootschalige muziekevenement in Nederland’ zijn wij de grootste speler en daar zijn wij best een beetje trots op! Onze missie: Iedere reis 5 sterren! Hoe we dat bereiken? Door de feedback van onze klanten om te

Bekijk vacature »

Medior/Senior Backend Developer

IT Recruitment is voor haar klant in Rijswijk op zoek naar Backend Developer. Als software engineer ben je gedreven in het bouwen, onderhouden en verbeteren van de kernproducten en -diensten, die de oplossingssuites vormen voor de producten en applicaties van de organisatie. Uitdagingen waar je onder andere mee te maken krijgt, zijn het implementeren van business logica, het analyseren en oplossen van problemen die door de klanten worden gemeld, het begrijpen en verbeteren van het datamodel met behulp van een SQL-serverdatabase, ervoor zorgen dat onze kernproducten ook toegankelijk zijn voor webtoepassingen via API’s en het handhaven van beveiligingsprincipes. Verantwoordelijkheden Software

Bekijk vacature »

Back-End Developer Java

APPLICANTS MUST LIVE IN THE NETHERLANDS As a Back End Developer you will be responsible to maintain and continuously develop new features and functionality in the micro-service environment. Being a part of the back end team you will work in multidisciplinary squads and have the unique chance to continuously develop and improve the technology stack. Client Details APPLICANTS MUST LIVE IN THE NETHERLANDS Key-Account of Michael Page / Famous A-Brand Description APPLICANTS MUST LIVE IN THE NETHERLANDS As a Back End Developer you will be responsible to maintain and continuously develop new features and functionality in the micro-service environment Being

Bekijk vacature »

Embedded Software Developer (C, C++)

For our high-tech business partner, we are in search of a Software Design Engineer / Software Developer with a MSc. or BSc. In Computer Science and relevant experience in C, C++. Do you like to work in a challenging environment in which you are able to work on world changing technology? Read on and apply! Functie As a Software Design Engineer / Software Developer you are responsible for the development and realization of software solutions to make the machines of our business client run. It is your challenge to make the machines run as smoothly as possible, so that they

Bekijk vacature »

PHP Developer (junior)

Als Junior PHP developer werk jij mee aan de uitbreiding van onze SaaS applicatie. Je bouwt aan nieuwe functionaliteiten, verbetert ons Content Management Systeem op basis van Symfony en optimaliseert de gebruiksvriendelijkheid. Alles valt te leren als je maar affiniteit hebt met code. We vinden nieuwsgierigheid een groot goed. Ons motto is dan ook: alles valt te leren als je maar nieuwsgierig bent! Je werkt aan een mooi product dat continu uitgebreid wordt en de potentie heeft om de wereld over te nemen! Naast het meewerken aan de uitbreiding van onze SaaS applicatie, werk je ook aan specifieke modules voor

Bekijk vacature »

Group Netwerk & Service Desk Administrator

Group Netwerk & Service Desk Administrator 32 – 40 uur per week, Burg Groep B.V. te Heerhugowaard Burg Group is een internationaal familiebedrijf met productiefaciliteiten in 5 verschillende landen waarvandaan we naar ruim 30 landen exporteren. Hiermee zijn we de grootste azijnproducent van Europa! Binnen de gehele Burg Group wordt veel waarde gehecht aan pro-activiteit, innovatie en duurzaamheid. Om goed ons werk te kunnen doen is het voor onze organisatie zeer belangrijk dat wij beschikken over een goede IT- Infrastructuur. Wegens tijdelijke vervanging zijn wij op zoek naar een Group Netwerk & Service Desk Administrator. Ben je een aanpakker, en

Bekijk vacature »

Junior Software Developer Energietransitie HBO/WO

Bedrijfsomschrijving Wij zoeken voor een jong bedrijf dat zich richt op de energietransitie naar een Junior Software Developer op HBO of WO niveau! Deze organisatie richt zich op verduurzaming van woningen in Nederland en dat doen zij door het aanbieden van slimme (monitoring) software. Deze tech scale-up heeft een eigen ontwikkelteam en kent een platte organisatiestructuur. Dit vraagt om een actieve inzet van iedere medewerker, maar ook een stukje eigen zelfstandigheid. Er wordt hier hard gewerkt aan prachtige software, kom jij het team ondersteunen? Ben jij net klaar met je HBO of WO studie in de richting van ICT, of

Bekijk vacature »

Fullstack developer (VueJS)

Frontend Developer / Full Stack developer Wij zijn de digitale motor van Hypotheken! Wij zijn trots dat we met onze afdeling de afstand tussen de bank op het gebied van hypotheken en de klant verkleinen. Zo hebben we onder andere digitaal ondertekenen mogelijk gemaakt, zijn alle klantbrieven gedigitaliseerd, hebben we een duurzame hypotheekvorm gelanceerd en draaien veel van onze systemen in de cloud. De Software Factory is een onderdeel van Hypotheken. Wij zorgen er samen met onze collega's van Florius voor dat 450.000 klanten zelf of via hun adviseur online hun hypotheek kunnen regelen. Wij maken dit mogelijk door het

Bekijk vacature »

Java Algorithms Developer

In the Applications Algorithms group we are responsible for the development and implementation of the common algorithms that are then used by other teams to develop applications to optimize the production process of our customers. We are a group of experts on mathematics, algorithms, numerical methods and software engineering. Functie Job Mission Collaborate with our experts developing or improving algorithms / mathematical models and contribute to the development from a software point of view; Create a solid software design for algorithms or parts of it, where speed and memory usage should be optimized; Write quality code that is easy to

Bekijk vacature »

Stage: Super programmeurs welkom (In Limburg)

Wat ga je doen? Je bouwt mee aan het CMS Serena. Je bouwt mee aan werken-bij websites van klanten. Je helpt met de koppelingen bouwen tussen onze werken-bij websites en diverse software pakketten. Over welke vaardigheden beschik je? Programmeren in PHP. Communicatief vaardig. Teamspeler. Eigen mening. Wat bieden we? 70% van al onze medewerkers hebben ooit stage gelopen bij Getnoticed. We zijn een gezellig bourgondisch bedrijf dat werkt voor de top van Nederland (ABN Amro, T-Mobile, Coolblue en meer). De volgende opties zijn mogelijk Een leerplaats die ook geschikt is voor minder validen Mogelijkheden voor zij-instromers

Bekijk vacature »
Snelle Jaap

Snelle Jaap

27/06/2019 13:35:53
Quote Anchor link
Ik heb een recursief menu script dat oneindig niveau's diep kan gaan aan de hand van parents en subs maar nu loop ik tegen een probleem aan.

Dit is de situatie:

Momenteel is het menu opgebouwd uit categorieën, dat houd in, hoofdcategorieen en subcategorieen, je kan die oneindig door linken onder elkaar. Dat werkt prima maar nu heb ik in mijn CMS ook `artikelen` dit zijn pagina's die alleen maar onder categorieën kunnen hangen en dus niet oneindig diep, deze gaan maar 1 niveau diep, altijd onder een categorie.

parent_id is het id waarmee een categorie aan een andere categorie is gekoppeld
catid is het id waarmee een artikel aan een categorie is gekoppeld

Het lukt mij niet dit artikelen te tonen in mijn menu.

Momenteel is dit de hoofdquery die alle categorieen ophaalt:

SELECT cat.id as cat_id, cat.level, cat.parent_id, cat.title as cat_title, cat.alias as cat_alias, cat.published, cat.rgt, cnt.state, cnt.id as content_id, cnt.catid, cnt.title as content_title, cnt.alias as content_alias
FROM snm_categories cat
LEFT JOIN snm_content cnt
ON cnt.catid = cat.id
WHERE cat.id NOT IN (1, 2, 3, 4, 5, 7, 8)
AND cat.published = 1
GROUP BY cat.id
ORDER BY cat.rgt ASC

Op de volgende manier stop ik dan alles in een menu:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<div id="main-menu" class="main-nav zn_mega_wrapper ">
  <ul id="menu-main-menu" class="main-menu zn_mega_menu">
    <li><a href="home">Home</a></li>
    <?PHP
    $alias
= $_GET['alias'];
    //Haal alle categorieen en check gelijk of de desbetreffende categorie artikelen onder zich heeft hangen.
    $menu = "
    SELECT cat.id as cat_id, cat.level, cat.parent_id, cat.title as cat_title, cat.alias as cat_alias, cat.published, cat.rgt, cnt.state, cnt.id as content_id, cnt.catid, cnt.title as content_title, cnt.alias as content_alias
    FROM snm_categories cat
    LEFT JOIN snm_content cnt
    ON cnt.catid = cat.id
    WHERE cat.id NOT IN (1, 2, 3, 4, 5, 7, 8)
    AND cat.published = 1
    GROUP BY cat.id
    ORDER BY cat.rgt ASC"
;
    $menuconn = $conn->query($menu);
    // Maak een nieuwe array om te vullen met onderstaand resultaat
    $menuData = array(
        'items' => array(),
        'parents' => array()
    );

    // Maak een nieuwe array met simpelweg items en parents, welke gekoppeld zitten aan cat_id/parent_id
    while($menu = $menuconn->fetch_assoc())
    {

        $menuData['items'][$menu['cat_id']] = $menu;
        $menuData['parents'][$menu['parent_id']][] = $menu['cat_id'];
    }


    // Functie om menu te maken, $parentId is 1 (de categorieen die geen parent hebben)
    function buildMenu($parentId, $menuData)
    {

        $html = '';
        if (isset($menuData['parents'][$parentId]))
        {

            //Als parent_id gelijk is aan 1 gooi een li eromheen (want het is geen subcat) anders een ul
            if($parentId == '1'){
              $html = '<li>';
            }
else{
              $html = '<ul class="sub-menu">';
            }

            foreach ($menuData['parents'][$parentId] as $itemId)
            {

                $html .= '<li class="menu-item"><a href="info/'.$menuData['items'][$itemId]['cat_alias'].'">'.$menuData['items'][$itemId]['cat_title'].'</a>';

                // Voer deze functie uit binnen de functie loop (recursief)
                $html .= buildMenu($itemId, $menuData);

                $html .= '</li>';
            }

            //Als parent_id gelijk is aan 1 gooi een li eromheen (want het is geen subcat)
            if($parentId == '1'){
              $html .= '</li>';
            }
else{
              $html .= '</ul>';
            }
        }

        return $html;
    }

    // Echo het resultaat van de functie en geef 1 mee als parent_id
    echo buildMenu(1, $menuData);
    ?>

  </ul>
</div>


Nu probeer ik de artikelen op deze manier erbij te plaatsen:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
<div id="main-menu" class="main-nav zn_mega_wrapper ">
  <ul id="menu-main-menu" class="main-menu zn_mega_menu">
    <li><a href="home">Home</a></li>
    <?PHP
    $alias
= $_GET['alias'];
    //Haal alle categorieen en check gelijk of de desbetreffende categorie artikelen onder zich heeft hangen.
    $menu = "
    SELECT cat.id as cat_id, cat.level, cat.parent_id, cat.title as cat_title, cat.alias as cat_alias, cat.published, cat.rgt, cnt.state, cnt.id as content_id, cnt.catid, cnt.title as content_title, cnt.alias as content_alias
    FROM snm_categories cat
    LEFT JOIN snm_content cnt
    ON cnt.catid = cat.id
    WHERE cat.id NOT IN (1, 2, 3, 4, 5, 7, 8)
    AND cat.published = 1
    GROUP BY cat.id
    ORDER BY cat.rgt ASC"
;
    $menuconn = $conn->query($menu);
    // Maak een nieuwe array om te vullen met onderstaand resultaat
    $menuData = array(
        'items' => array(),
        'parents' => array()
    );

    // Maak een nieuwe array met simpelweg items en parents, welke gekoppeld zitten aan cat_id/parent_id
    while($menu = $menuconn->fetch_assoc())
    {

        $menuData['items'][$menu['cat_id']] = $menu;
        $menuData['parents'][$menu['parent_id']][] = $menu['cat_id'];

        // Hier haal ik de artikelen onder de juiste categorie
        $submenu = "SELECT * FROM snm_content WHERE catid = '".$conn->real_escape_string($menu['cat_id'])."' AND catid NOT IN (8) AND state = 1 ORDER BY ordering";
        $submenuconn = $conn->query($submenu);
        while($submenu = $submenuconn->fetch_assoc()){
          $artikelsubs = '<li class="menu-item"><a href="info/'.$submenu['alias'].'">'.$submenu['title'].'</a>';
        }
    }


    // Functie om menu te maken, $parentId is 1 (de categorieen die geen parent hebben)
    function buildMenu($parentId, $menuData)
    {

        $html = '';
        if (isset($menuData['parents'][$parentId]))
        {

            //Als parent_id gelijk is aan 1 gooi een li eromheen (want het is geen subcat) anders een ul
            if($parentId == '1'){
              $html = '<li>';
            }
else{
              $html = '<ul class="sub-menu">';
            }

            foreach ($menuData['parents'][$parentId] as $itemId)
            {

                $html .= '<li class="menu-item"><a href="info/'.$menuData['items'][$itemId]['cat_alias'].'">'.$menuData['items'][$itemId]['cat_title'].'</a>';
                // Voer deze functie uit binnen de functie loop (recursief)
                $html .= buildMenu($itemId, $menuData);

                $html .= '</li>';

            }

            //Als parent_id gelijk is aan 1 gooi een li eromheen (want het is geen subcat)
            if($parentId == '1'){
              $html .= '</li>';
              $html .= $artikelsubs;
            }
else{
              $html .= '</ul>';
            }
        }

        return $html;
    }

    // Echo het resultaat van de functie en geef 1 mee als parent_id
    echo buildMenu(1, $menuData);
    ?>

  </ul>
</div>
Maar helaas zie ik niks in de broncode staan of op de website qua artikelen. Weet iemand waar het misgaat?

Als ik de query in phpmyadmin test met bijvoorbeeld '9' op de plaats van '".$conn->real_escape_string($menu['cat_id'])."' dan krijg ik de juiste data te zien.
 
PHP hulp

PHP hulp

29/01/2022 03:20:04
 
Thomas van den Heuvel

Thomas van den Heuvel

27/06/2019 14:10:14
Quote Anchor link
Quote:
Als ik de query in phpmyadmin test met bijvoorbeeld '9' op de plaats van '".$conn->real_escape_string($menu['cat_id'])."' dan krijg ik de juiste data te zien.

Dit laatste vertelt je alleen dat de oorspronkelijke data die je ophaalt goed / volledig is.

Vervolgens stop je dit in een datastructuur.

En deze datastructuur voer je aan een functie.

Dit zijn dus meerdere stappen.

Controleer de datastructuur $menuData, bijvoorbeeld door deze naar het scherm te dumpen.

Deze regel:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
<?php
$menuData
['parents'][$menu['parent_id']][] = $menu['cat_id'];
?>

Is wellicht correct, maar dat zijn geen parents, maar children. Je voegt namelijk het huidige item toe als child van de parent :). En waarom zou je dat uberhaupt compliceren met twee subarrays? Nu kopieer je gewoon de "rauwe" kolomnamen van een recordrij ($menu) naar een array, maar je zou ook nettere/beter leesbare kolommen kunnen definiëren.

De naam $menuconn is ook misleidend. Dit is een result-object, geen connectie-object.

En dan de constructie van regel 23 t/m 34. Een query in een while-loop is vrijwel altijd een "code smell".

Ook het if-statement van regel 40 is niet nodig:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
if (isset($menuData['parents'][$parentId])) { ... }

Je roept namelijk buildMenu() aan in een loop waarin je precies deze items doorloopt, die hoef je dan na aanroep niet nogmaals te controleren...

Als je $menuData nu eens wat zinniger had gestructureerd, bijvoorbeeld door de keys van dit array simpelweg het categorie-id te laten zijn, dan had je met een array_keys() de keys van het array hierop direct (met één query) alle relevante artikelen op kunnen halen.

En als je van dit alles een class had gemaakt, dan hoef je ook niet elke functie-aanroep het hele array mee te geven, de datastructuur kun je opslaan als klasse-variabele.

Ik heb een deja vu. Ik weet vrij zeker dat ik je (mogelijk in een ver verleden) als eens heb voorgesteld om het bouwen van de datastructuur en het weergeven van deze structuur in een HTML-menu beter in afzondering kan doen. Sterker nog, de hele bovenstaande aanpak passeerde daarin volgens mij de revue.

Ik zou dus die datastructuur ($menuData) eens onder de loep nemen en herstructureren zodat je hier handiger gebruik van kunt maken.

Functie om een en ander in leesbare vorm te dumpen:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
// escape functie
function escape($in) {
    return htmlspecialchars($in, ENT_QUOTES, 'UTF-8'); // aangenomen dat je UTF-8 gebruikt
}

// veilige dump functie (alles wordt weergegeven als tekst en wordt niet geinterpreteerd als HTML/JS)
function dump($in) {
    if (is_array($in)) {
        $in = print_r($in, true);
    }

    echo '<pre>'.escape($in).'</pre>';
}

?>
Gewijzigd op 28/06/2019 12:43:56 door Thomas van den Heuvel
 
Snelle Jaap

Snelle Jaap

02/07/2019 13:47:51
Quote Anchor link
@Tomas van heuvel,

Klopt ik heb al een keer eerder iets gevraagd over dit script. Bedankt voor de uitleg ik ga proberen er iets mee te doen.
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.