Recursief menuscript uitbreiden

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

AngularJS Developer

Wat je gaat doen: Of beter nog, wat wil jij doen? Bij DPA GEOS werken onze consultants als Developer in Agile teams bij onze klanten en zijn ze verantwoordelijk voor de grotere webapplicaties. Wil jij dit ook, want we zijn op zoek naar enthousiaste Developers om ons development team te versterken. Je bent creatief en draagt met je enthousiasme positief bij aan de teamgeest binnen een projectteam. Je gaat webapplicaties maken voor verschillende opdrachtgevers in jouw regio. Je bent een professional die het IT-vak serieus neemt en kwaliteit levert. Je leert snel vanwege je diepgaande interesse in het applicatie landschap.

Bekijk vacature »

PHP detachering bij startups tot multinationals, o

Bedrijfsinfo Veel detachering organisaties denken vanuit uit belang van hun klanten en kijken welke consultants daar goed op passen. Wat deze organisatie onderscheid is dat ze met jou gaan kijken waar je goed in bent, waar je je in wilt gaan ontwikkelen en wat je interesses zijn. Op basis daarvan worden de klanten geselecteerd waarvan je voor een periode van minimaal 3 maanden mee gaat draaien in het team. Dit kan zijn in een rol als medior, senior, lead developer of architect. Hierbij krijg je de kans om zichzelf te ontwikkelen binnen allerlei grote bekende organisaties. Omdat deze detacheringclub met

Bekijk vacature »

Senior Full-Stack .NET Developer Automotive

Organisatie De organisatie is ooit begonnen in 1996 met één doel, namelijk; de beste IT oplossing voor de automotive branche! “waar anderen oplossingen zoeken om kosten te drukken, zijn wij heel erg actief in het commercieel opkrikken van de omzet” aldus, de directeur. Het bedrijf bestaat uit 3 takken, die samen de bermuda driehoek vormen voor deze branche. Er is gewoonweg geen ontkomen aan de tools en software die in de afgelopen 20 jaar waterdicht is ontwikkeld! Samen leveren ze een totaalpakket waarmee de klant/eindgebruiker niet alleen een meedenkend product binnenhaalt, maar ook een werknemer aanneemt die de team uitdaagt!

Bekijk vacature »

Medior Java Developer met drie jaar werkervaring

Vacature Omschrijving De volgende relatie, gevestigd in Amsterdam, heeft een platvorm ontwikkeld om online koopgedrag in kaart te brengen. Afgelopen jaar is dit getest door een internationale kledingketen en zij spreken van een platvorm dat eerste is in zijn soort. Functieomschrijving Dit tech bedrijf in Amsterdam is één van de weinige die machine Learning, deep Learning & software engineers combineert. Dit platvorm zal een nieuwe afdeling gaan vormen binnen en al bestaand organisatie dat sinds 2002 hard aan het groeien is. Je komt terecht in een multidisciplinair bedrijf met verschillende nationaliteiten. Voertaal is Engels en de organisatie ligt op steenworp

Bekijk vacature »

Junior C# ASP.NET developer

Organisatie Voor deze organisatie ben ik op zoek naar een junior C# .NET developer met een HBO/WO achtergrond in informatica. Zij zijn al meer dan 15 jaar gespecialiseerd in het inzichtelijk maken van bedrijfsprocessen voor zowel middelgrote bedrijven als multinationals. De organisatie heeft haar focus gelegd op verschillende producten die zij in house ontwikkelen. Zij ontwikkelen een applicatie waarmee er in een oogopslag verschillende KPI’s gemeten kunnen worden. Dit wordt gedaan voor grote en middelgrote organisaties, denk hierbij aan de berekening van een financiële forecast, de prestaties van verschillende business units of werknemers. Aan de hand van deze data kunnen

Bekijk vacature »

Start met het C# .NET IT-traineeship en word junio

Wat ga je doen? IT-traineeship bij YoungCapital NEXT In onze tweejarige IT-traineeships word jij opgeleid tot een gecertificeerd junior C# programmeur mét praktijkervaring. Je gaat je o.a. verdiepen in; SCRUM, OOP, EF, LINQ, ADO.NET, ASP. NET, MVC, Web API, RDBMS, SQL, Javascript, Ajax, AngularJS. Naast theoretische verdieping word je ook individueel uitgedaagd met praktijkopdrachten. De opleiding sluit je af met een eindopdracht waar je samen met iemand anders aan hebt gewerkt tijdens het traineeship en behaaal je het MCSD 70-483- en Scrum-certificaat. Op deze manier start je goed voorbereid om bedrijven te helpen met het ontwikkelen van nieuwe applicaties, of

Bekijk vacature »

Medior .NET Developer

Organisatie Ruim 15 jaar geleden is de organisatie opgericht en deze is gevestigd in regio Oss. Zij zijn specialist binnen hun vakgebied en worden door de grootste spelers op de markt benaderd voor de soft- en hardware die ze maken. Met een hechte groep collega’s heeft deze organisatie met hun producten bewezen dat zij een innovatieve speler zijn in de medische wereld. Momenteel draaien de producten die ze gemaakt hebben in meer dan 90% (!) van de operatiekamers van Nederlandse ziekenhuizen. Sterker nog, de producten die zij maken worden zelfs wereldwijd gebruikt voor het redden van levens! Hoezo een impact

Bekijk vacature »

Senior C# .NET developer / Werken met GIS / CAD te

Stel je eens het volgende voor. Je stapt elke ochtend de auto in, zet je favoriete nummer aan en pakt de snelste route naar je werk. Maar, wat je je niet bedenkt is dat Nederland tot een van de dichtst vertakte wegennetten ter wereld beschikt! Al die wegen moeten naadloos op elkaar aansluiten, rekening houdend met allerlei belangrijke factoren. Tijdens de bouw van zo een wegennet is het belangrijk om alle processen en informatie goed in de gaten te houden. Dit wordt gedaan middels GIS, een Geografisch Informatie Systeem en daar mag jij mee werken! Gelegen ten zuiden van Utrecht

Bekijk vacature »

Drupal developer

Functieomschrijving Heb jij enige ervaring met het ontwikkelen van Drupal? Krijg je daarnaast energie van het werken binnen een scrum team en het ontwikkelen van consistente functionaliteiten? Neem dan contact met mij op! Het ontwikkelen van Drupal; Het koppelen van systemen en modules; Het opleveren van zowel generieke als maatwerk oplossingen; Samen met het team nadenken over nieuwe mogelijkheden en dit middels scrumsprints van 2 weken uitwerken; Het reviewen van de code die door collega's isopgesteld. Functie-eisen Ervaring met het ontwikkelen van Drupal, bij voorkeur versie 8; Je hebt ervaring met Agile/Scrum en hebt ervaring met object georiënteerd programmeren; Ervaring

Bekijk vacature »

Senior PHP Developer en uitstekend secundair pakke

Functieomschrijving In de functie van Senior PHP programmeur word je met je team verantwoordelijk voor de technische backend applicatie. Je gaat je, samen met andere Developers en technisch projectleiders, buigen over applicaties, bouwen van nieuwe websites en andere systemen. Je wordt technisch aanspreekpunt voor je collega’s, dus zorg dat je verstand van zaken hebt! Je gaat aan de slag met PHP 5.3 OOP, framework als Symfony2, Zend of CakePHP (afhankelijk van de materie), MySQL, HTML, CSS, Javascript (jQuery), webservices en API’s, design patterns (MVC), UML en Git. Functie-eisen Minimaal 4 jaar of meer relevante PHP werkervaring Goede kennis van MySQL,

Bekijk vacature »

ABAP Developer

Functieomschrijving Heb jij de nodige ervaring met ABAP en ben jij toe aan een nieuwe uitdaging? Werk je graag in een internationaal bedrijf met een informele sfeer en flexibiliteit? Dan is deze vacature iets voor jou! Je richt je op SAP development werkzaamheden die voort komen uit optimalisatie-, migratie-, integratie- en innovatie trajecten; Je werkt met o.a. ABAP Eclipse, OOP, Webservices en HANA; Je hebt nauw contact met de functionele SAP specialisten om de wensen helder te krijgen waarna je dit vertaalt naar de technische oplossing; Je werkt in een Agile / Scrum werkomgeving; Je adviseert de organisatie op jouw

Bekijk vacature »

Medior / Senior Front-end Developer

Organisatie “Het grootste deel van je leven werk je, dus waarom zou het niet leuk zijn?”. Dit is het motto van deze organisatie! Op een unieke locatie is 10 jaar geleden deze organisatie gestart. Na al die jaren zijn ze uitgegroeid tot de marktleider in hun niche en bouwen zij voor de meest vette klanten, webapplicaties, high traffic platformen, intelligente apps en nog veel meer innovatieve projecten. Binnen deze organisatie werk je samen met echte techneuten en creatievelingen. Met uitzicht over hun eindeloze bron van inspiratie werken zij elke dag hard aan het verwezenlijken van hun ambities. Deze wordt duurzaam

Bekijk vacature »

.NET Developer / Sitecore / ASP.NET MVC / Inhouse

Functieomschrijving Would you like to work on different projects and develop online platforms for various clients in a software house? Are you getting excited about working for different well-known brands at inhouse projects? Apply now! Develop diverse online platforms; Work closely with the Front-End developers and other team members; Communicating with clients; Watch over the architecture of the applications. Functie-eisen You have a University BSc. or MSc. degree, preferably in the area of Informatics; You have at least 3 years experience with .NET; You have been working in an Agile/Scrum/DevOps environment; You have experience with MVC, Cloud, Web Services and

Bekijk vacature »

Junior PHP Developer

Organisatie Dit ambitieuze bedrijf is 16 jaar geleden gestart en heeft zich sindsdien ontwikkelt van website ontwikkelaar tot het maken van complexe maatwerk oplossingen. Ze hebben een groot klantenbestand en ze maken bij voorbeeld de website voor een grote supermarktketen, koppelingen voor de overheid en zo hebben ze zelf ook eigen webshops in beheer, gewoon omdat het kan. Dit maken ze met ontzettend veel passie en “state of the art” soft en hardware. Wanneer een deadline is gehaald of een project goed is afgerond wordt er zeker een feestje gevierd. Deze organisatie vindt het ook belangrijk om te investeren in

Bekijk vacature »

Xamarin Developer regio Utrecht

‘Duurzaamheid is geen begrip. Duurzaamheid is een mindset’ Hoe vaak stap je s’ ochtends de auto in op weg naar je werk, denkend aan hoe slecht het is voor het milieu dat je weer de auto pakt. Je weet dat je ook prima met de fiets naar je werk kan, maar het is zo lekker snel en gemakkelijk. Maar heb je er weleens over nagedacht hoeveel CO2 je de lucht in slingert door dat ritje naar je werk? En hoeveel calorien je verbrandt als je een keer de fiets pakt? Men zegt altijd dat milieubewust handelen een kwestie is van

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

20/07/2019 08:14:39
 
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.