Waarom zie ik deze menuknop niet met dit script?

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Ventilatiesysteem Productontwikkelaar HBO WO Verwa

Samengevat: Zij bieden flexibele ventilatiematerialen, geluidsdempers, rookgasafvoer producten en industrieslangen. Ben jij een technisch productontwikkelaar? Heb jij ervaring met het ontwikkelen van nieuwe producten? Vaste baan: Technisch Productontwikkelaar HBO WO €3.000 - €4.000 Zij bieden een variëteit aan flexibele ventilatiematerialen, geluiddempers, rookgasafvoer producten, industrieslangen en ventilatieslangen voor de scheepsbouw. Met slimme en innovatieve materialen zorgen wij voor een gezonde en frisse leefomgeving. Deze werkgever is een organisatie die volop in ontwikkeling is met hardwerkende collega's. Dit geeft goede ontwikkelingsmogelijkheden. De branche van dit bedrijf is Techniek en Engineering. Functie: Voor de vacature als Technisch Productontwikkelaar Ede Gld HBO WO ga

Bekijk vacature »

Snelle Jaap

Snelle Jaap

03/05/2018 15:47:38
Quote Anchor link
Ik heb een tijd geleden een recursief menu op mijn site gezet. Deze pakte die functie op alle knoppen in het menu.

Nu wil ik deze functie alleen uitvoeren voor 1 knop, namelijk verhuur, en de rest wil ik zoals mijn oude menuscript.

Dus alleen wanneer er over verhuur wordt gehovered (cat_id 22) dan mag er een oneindig submenu uitklappen.

Ik heb op deze manier een poging gewaagd:

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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
<?PHP
//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)
AND cat.published = 1
AND cat.level = 1
GROUP BY cat.id
ORDER BY cat.rgt ASC"
;
$menuconn = $conn->query($menu);
//Loop het resultaat
while($menu = $menuconn->fetch_assoc()){
  $cat_ids = '';
  $subcatmenulijst = '';
  $subcats = '';
  //Code om te checken of de huidige pagina gelijk is aan de alias
  if($menu['alias'] == $alias){
    $class='current';
  }
else {
    $class = '';
  }


  //Stop alle ids van de categorieen in een array
  $cat_ids[] = $menu['cat_id'];

  //Implodeer ze met commas ertussen zodat ze bruikbaar zijn in een query
  if(!empty($cat_ids)) {
    $useableids = implode(',', $cat_ids);
  }

  // Query voor de subcats
  $subcatmenu         = 'SELECT * FROM snm_categories WHERE parent_id IN ('.$conn->real_escape_string($useableids).') and published = 1 ORDER BY lft';
  $subcatmenucon      = $conn->query($subcatmenu);
  while($subcatmenu   = $subcatmenucon->fetch_assoc()){
    $subcatmenulijst .= '<li><a href="info/'.$subcatmenu['alias'].'.html">'.$subcatmenu['title'].'</a></li>';
  }

  // Als
  if(!empty($subcatmenulijst)){
    $subcats = 'true';
  }

  // Als het niet de `verhuur` knop is
  if($menu['cat_id'] != 22){
  //Loop alle categorieen
  $menuresult .= '<li class="'.$class.'"><a href="info/'.$menu['cat_alias'].'.html">'.$menu['cat_title'].'</a>';
  //Haal alle artikelen op waar het catid gelijk is aan het id van een categorie (binnen bovenstaande loop, zodat het gebeurd voor elke categorie)
  $submenu = "SELECT * FROM snm_content WHERE catid = '".$conn->real_escape_string($menu['cat_id'])."' AND state = 1 ORDER BY ordering";
  $submenuconn = $conn->query($submenu);

    //Als er het id van een artikel niet leeg is (dus als er artikelen onder hangen) OF als er subcategorieeen aanwezig zijn:
    if(!empty($menu['content_id']) OR $subcats == 'true'){
      $menuresult .= '<ul class="sub-menu">';
      //Loop het resultaat
      while($submenu = $submenuconn->fetch_assoc()){
        $menuresult .= '<li><a href="'.$submenu['alias'].'.html">'.$submenu['title'].'</a></li>';
      }

      // Plak de categorieen onder artikelen
      $menuresult .= $subcatmenulijst;
      $menuresult .= '</ul>';
    }

  // Maar als het dat wel is:
  }else{
    ////
    //Haal alle categorieen en check gelijk of de desbetreffende categorie artikelen onder zich heeft hangen.

    $menucatalogus = "
    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
    FROM snm_categories cat
    WHERE cat.id NOT IN (1, 2, 3, 4, 5, 7)
    AND cat.published = 1
    GROUP BY cat.id
    ORDER BY cat.rgt ASC"
;
    $menucatalogusconn = $conn->query($menucatalogus);

    $menuData = array(
        'items' => array(),
        'parents' => array()
    );


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

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

        $arr[] = $menucatalogus;
    }


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

        //$menuresult = '';
        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 == '22'){
              $menuresult = '<li>';
            }
else{
              $menuresult = '<ul class="sub-menu">';
            }

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

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

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

        return $menuresult;
    }

    // Echo het resultaat van de functie en geef 1 mee als parent_id
    echo buildMenu(1, $menuData);
    ////
  }
  $menuresult .= '</li>';
}

echo $menuresult;
?>


Dit laat alleen niet mijn knop 'verhuur' zien. Hoe komt dat?

Deze query:

This query:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
    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
    FROM snm_categories cat
    WHERE cat.id NOT IN (1, 2, 3, 4, 5, 7)
    AND cat.published = 1
    GROUP BY cat.id
    ORDER BY cat.rgt ASC


bevat:

Afbeelding

En deze query:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
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)
    AND cat.published = 1
    AND cat.level = 1
    GROUP BY cat.id
    ORDER BY cat.rgt ASC


bevat:

Afbeelding
Gewijzigd op 03/05/2018 15:48:12 door Snelle Jaap
 
PHP hulp

PHP hulp

19/04/2024 02:03:14
 
Thomas van den Heuvel

Thomas van den Heuvel

03/05/2018 16:24:47
Quote Anchor link
Ho, stop. Kwam dit niet ook al ter sprake in vorige topics hierover: het scheiden van de verantwoordelijkheden.

Als je nu eerst eens functionaliteit maakt voor het bouwen van een generieke datastructuur (dit hoef je maar 1x te doen) en daarna je manipulaties toepast op deze datastructuur, of liever gezegd, op de weergave hiervan, scheelt je een hoop werk.

Nu ben je opnieuw een specifiek wiel aan het uitvinden, en daarmee maak je generieke code weer specifiek, dan ga je de verkeerde kant op.

Een eerste stap in de structurering hiervan is een soort van functie of verzameling van functies (of methoden in een klasse) voor het bouwen van een datastructuur die de boomstructuur van je site voorstelt. Als je dat eenmaal voor elkaar hebt (dat had je in principe al, wellicht niet helemaal op deze manier geformaliseerd?) dan kun je allerlei manipulaties gaan uitvoeren op deze gegenereerde boomstructuur, maar je hoeft dat ding dan dus niet elke keer from scratch op te trekken. Als je dat wel elke keer zou doen dan gaan er ook allerlei flarden code die ongeveer hetzelfde doen rondzwerven in je codebase. Dit wil je echt niet.

Bouw eerst die boom, en doe dan je ding met die gegenereerde boom.
 
Snelle Jaap

Snelle Jaap

04/05/2018 10:11:31
Quote Anchor link
Die boom heb ik al, alle gegevens staan in mijn database en worden opgehaald met een query.

Deze code:

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
<?PHP
$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)
    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="'.$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);
?>


Heeft qua data alles wat ik nodig heb. Alleen hoe kan ik makkelijk onderscheid maken?

Mijn huidige menu (bovenstaande code) heeft alleen maar categorieen en subcategorieen. Maar ik heb naast die categorieen nog één optie, een artikel die onder een categorie kan hangen.

Dus: een categorie kan aan een categorie hangen en wordt dus een subcategorie in mijn menu. Maar een artikel kan ook aan een categorie gehangen worden, maar weer niet aan een ander artikel, je hebt dus geen sub artikelen.

De structuur is als volgt:

snm_categories (de categorieen)
id - id van de categorie
parent_id id van de categorie waar deze categorie onder hangt, 1 als hij geen parent heeft

snm_content (de artikelen)
id - het id van het artikel
catid - het id van de categorie waar die aanhangt (zelfde als id bij snm_categories)

Met de artikelen gebeurt er nu nog niks in mijn menu script, maar de data haal ik wel op met mijn query.

Ik wil voor de artikelen een andere link dan voor de categorieen zodat deze via .htaccess doorverwijst naar een andere page.

Kan dat met mijn huidige script of zal ik deze compleet moeten ombouwen?
 
Thomas van den Heuvel

Thomas van den Heuvel

04/05/2018 12:50:24
Quote Anchor link
Ik denk dat je hier weer een aantal dingen op een hoop gooit. Het makkelijkste blijft gewoon om deze problemen te splitsen.

Quote:
Dit laat alleen niet mijn knop 'verhuur' zien. Hoe komt dat?

Mogelijk vanwege het volgende:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
<?php
while($menu = $menuconn->fetch_assoc()){ // regel 15
  $cat_ids = ''; // regel 16
  // ...

  $cat_ids[] = $menu['cat_id']; // regel 27
  // ...

}
?>

Oftewel: elke stap in de while-loop kieper je doodleuk $cat_ids leeg.

Daarnaast: nog een query in een while-loop? Waar is dat voor nodig? De hele menu-opbouw kan met één (of twee, voor de artikelen wellicht) queries.
Maar ook: een functiedeclaratie in een while-loop? Krijg je daar geen foutmeldingen over?

Quote:
Kan dat met mijn huidige script of zal ik deze compleet moeten ombouwen?

Hm - je zou een aparte entry "articles" kunnen aanmaken in je datastructuur? Daarnaast is wellicht een betere benaming voor "parents" "children" want het betreft nazaten (onderliggende elementen), geen ouders (bovenliggende elementen).

Ik zou dit dus opsplitsen:
stap 1: bouw (op een efficiënte manier) een datastructuur waar ALLES in zit, ook al heb je specifieke wensen.
stap 2: bouw de HTML-menu's waarin je specifieke dingen eruitfiltert of juist laat zien op grond van de boom uit stap 1 waarin alles zit.
 
Willem vp

Willem vp

04/05/2018 14:42:50
Quote Anchor link
> Maar ook: een functiedeclaratie in een while-loop? Krijg je daar geen foutmeldingen over?

De functie staat in een else-blok, dus zolang de conditie ervoor zorgt dat dat else-blok maar 1x wordt aangeroepen, gaat het goed. Als er echter twee menu-opties zijn met cat_id == 22, krijg je een redeclaration error.
 
Thomas van den Heuvel

Thomas van den Heuvel

04/05/2018 14:47:10
Quote Anchor link
Willem vp op 04/05/2018 14:42:50:
De functie staat in een else-blok, dus zolang de conditie ervoor zorgt dat dat else-blok maar 1x wordt aangeroepen, gaat het goed. Als er echter twee menu-opties zijn met cat_id == 22, krijg je een redeclaration error.

Akkoord, maar simpelweg omdat iets werkt maakt het nog niet juist :).
 



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.