Laat dropdown ul niet zien met twee voorwaardes werkt niet

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Snelle Jaap

Snelle Jaap

13/02/2018 13:49:12
Quote Anchor link
Ik heb een eigen menu script gemaakt die werkt op een joomla database. Een joomla database werkt met categorieen die aan een parent categorie gehangen kunnen worden en artikelen die aan een categorie gehangen kunnen worden.

Daar heb ik deze code mee gemaakt:

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
<?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)
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 = '';
  $projectenmenulijst = '';
  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);
  }


  //Wanneer het id 10 is van projecten voer dan de volgende code uit (2 niveaus diep) -- deze code is even uitgecommend, want hij moet het voor alles doen, niet alleen id 10
  // if($menu['cat_id'] == 10){

    $projectenmenu    = 'SELECT * FROM snm_categories WHERE parent_id in ('.$conn->real_escape_string($useableids).') and published = 1 ORDER BY lft';
    $projectenmenucon = $conn->query($projectenmenu);
    while($projectenmenu     = $projectenmenucon->fetch_assoc()){
      $projectenmenulijst .= '<li><a href="info/'.$projectenmenu['alias'].'.html">'.$projectenmenu['title'].'</a></li>';
    }

  // } else {
  //   $projectenmenulijst .= '';
  // }

  //Loop alle categorieen

  $menuresult .= '<li class="'.$class.'"><a href="info/'.$menu['cat_alias'].'.html">'.$menu['cat_title'].''.$projecten.''.$hasdropdown1.'</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);
  //Check of de categorie artikelen onder zich heeft of andere categorieen
  if(!empty($menu['content_id']) OR $menu['cat_id'] != ''){
    $menuresult .= '<ul class="sub-menu" role="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 .= $projectenmenulijst;
  $menuresult .= '</li>';

  //Check of de categorie artikelen onder zich heeft of andere categorieen
  if(!empty($menu['content_id']) OR $menu['cat_id'] != ''){
    $menuresult .= '</ul>';
  }
}

echo $menuresult;
?>


Ik wil hiermee dus zowel artikelen als categorieen in een dropdown laten zien wanneer die bestaan. Een toplevel categorie kan dus zowel een subcategorie aan zich hebben hangen als een artikel. Dit werkt. Maar elk menu item laat nu de ul zien onder zich, oftewel deze code:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
  //Check of de categorie artikelen onder zich heeft of andere categorieen
  if(!empty($menu['content_id']) OR $menu['cat_id'] != ''){
    $menuresult .= '<ul class="sub-menu" role="menu">';
  }

  //Check of de categorie artikelen onder zich heeft of andere categorieen
  if(!empty($menu['content_id']) OR $menu['cat_id'] != ''){
    $menuresult .= '</ul>';
  }


Er klopt dus iets niet met deze if neem ik aan. Want als er geen artikelen zijn en geen categorieen onder een topcategorie laat hij nog steeds $menuresult zien met daarin de <ul>.

Hoe komt dit?

Als ik het menu inspecteer zie ik dat er 100% niets in deze ul's zit behalve waar wel wat in hoort te staan.
Gewijzigd op 13/02/2018 13:51:23 door Snelle Jaap
 
PHP hulp

PHP hulp

26/09/2020 00:27:42
 
Thomas van den Heuvel

Thomas van den Heuvel

13/02/2018 20:00:43
Quote Anchor link
Zou het niet veel makkelijker zijn om eerst een datastructuur (boom in de vorm van een genest array) van categorieën + artikelen op te tuigen (dit kost je exact 2 queries) en vervolgens met een zichzelf aanroepende (recursieve) functie een geneste unordered list te genereren met behulp van een whitelist van categorieën waarin je geïnteresseerd bent?

Hiermee deel je je probleem op in stukken, waarbij de onderdelen mogelijkerwijs ook nog eens herbruikbaar zijn.
 
Snelle Jaap

Snelle Jaap

16/02/2018 14:59:15
Quote Anchor link
Thomas van den Heuvel op 13/02/2018 20:00:43:
Zou het niet veel makkelijker zijn om eerst een datastructuur (boom in de vorm van een genest array) van categorieën + artikelen op te tuigen (dit kost je exact 2 queries) en vervolgens met een zichzelf aanroepende (recursieve) functie een geneste unordered list te genereren met behulp van een whitelist van categorieën waarin je geïnteresseerd bent?

Hiermee deel je je probleem op in stukken, waarbij de onderdelen mogelijkerwijs ook nog eens herbruikbaar zijn.

Ik snap niet wat je bedoelt.
 
- Ariën -
Beheerder

- Ariën -

16/02/2018 15:25:54
Quote Anchor link
Ik denk dat je hier wat aan hebt:
https://crisp.tweakblogs.net/blog/317/formatting-a-multi-level-menu-using-only-one-query.html

Puur voor het voorbeeld dan, want het spreekt voor sich dat de mysql-functions binnenkort verleden tijd zijn.
Zo te zien kan dit ook al in een enkele query.
Gewijzigd op 16/02/2018 15:29:26 door - Ariën -
 
Thomas van den Heuvel

Thomas van den Heuvel

16/02/2018 16:40:25
Quote Anchor link
Snelle Jaap op 16/02/2018 14:59:15:
Ik snap niet wat je bedoelt.

Op dit moment (oorspronkelijke bericht) probeer je drie dingen tegelijkertijd te doen (het lijkt wel een KinderSurprise):
- het opbouwen van een dataset
- het filteren van de categorieën waarin je geïnteresseerd bent
- het genereren van de bijbehorende HTML

En dit alles ook nog eens met een héleboel queries. Als je nu eens eerst een dataset maakt (een gestructureerd (en eventueel genest) array) waarin je de categorieën inventariseert (1 query), vervolgens haal je alle artikelinformatie op (1 query) en hang je deze in deze dataset, of in ieder geval de artikel-id's. Eventueel maak je voor artikelen een apart lijstje (aparte dataset).

En dan schrijf je een loopje, of wellicht beter, een functie die je aan kunt roepen met de hoofdcategorieën waarin je geïnteresseerd bent, en deze haalt alle categorieën op, eventueel direct in de goede volgorde voor het weergeven.

En dan schrijf je wat code die deze opgehaalde informatie ophaalt en gebruikt om een menuutje uit te draaien.

Het voordeel van deze aanpak is (op zijn minst) tweeledig:
- je past een verdeel-en-heers strategie toe waarbij je het probleem opdeelt in deelproblemen
- de afzonderlijke onderdelen zijn herbruikbaar, dus als je dan in het vervolg een menu moet genereren van een of meer categorieën dan roep je in het ideale geval een reeds geschreven functie aan met andere parameters

Oftewel, stop eens met alle geweld direct naar een oplossing te werken maar schrijf eens wat, weliswaar uitgebreidere, maar slimmere, code.

De dataset voor de categorieën ziet er bijvoorbeeld als volgt uit:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
<?php
$categories
= array(
    // root element
    0 => array(
        'parent'        => false,
        'children'      => array(),
        'articleIds'    => array(),
        'id'            => false,
        'title'         => '',
    ),
);

?>

Waarbij het bovenstaande element het root-element is (waar je alle hoofdcategorieën aan koppelt).
Vervolgens haal je alle categorieën met één query op (orden op id, en dan op parent id) en hang je deze in de datastructuur waarbij je tevens parent en children aan elkaar koppelt (als een item een parent heeft), met code die lijkt op:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
<?php
// voeg eerst item toe aan de datastructuur
$parentId = $row['parent_id'] === NULL ? 0 : $row['parent_id'];
$categories[$row['id']] = array(
    'parent' => $parentId,
    // etc.
);

// koppel dit item vervolgens aan de parent als child
// elke item heeft een parent, ook de hoofdcategorieën, deze hang je aan de root

$categories[$parentId]['children'][] = $row['id'];
?>

Vervolgens hang je alle artikelen in deze boom (onder articleIds van de juiste categorie), en daarna kun je alles doen met deze datastructuur wat je maar wilt.

Succes ermee.

EDIT: Een soortgelijk probleem met een nagenoeg dezelfde aanpak kun je hier terugvinden met als kanttekening dat je tijdens het opbouwen van de datastructuur ook dataverrijking kunt toepassen, zo zou je bijvoorbeeld de diepte van een element kunnen bijhouden als dit het later weergeven van een menu kan vereenvoudigen.
Gewijzigd op 16/02/2018 16:52:15 door Thomas van den Heuvel
 
Snelle Jaap

Snelle Jaap

20/02/2018 15:07:21
Quote Anchor link
Bedankt voor de uitgebreide uitleg. Ik ga is proberen of ik het op deze manier kan oplossen.

Toevoeging op 20/02/2018 15:07:22:

Bedankt voor de uitgebreide uitleg. Ik ga is proberen of ik het op deze manier kan oplossen.
 



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.