Hoe kan ik alle producten tellen binnen categorieen die ook subcategorieen hebben

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Technisch Ontwerper / Applicatie Ontwikkelaar

Technisch Ontwerper / Applicatie Ontwikkelaar Actief Wat ga je doen? Als Technisch Ontwerper / Applicatie Ontwikkelaar kom je te werken bij onze gerenommeerde klanten op projecten of opdrachten van omvang en formaat. Je bent verantwoordelijk voor het omzetten van functionele specificaties naar een technisch ontwerp, het ontwerp van programmaspecificaties voor toepassingen, de realisatie van (gewijzigde) programmaonderdelen en databestanden van toepassingen en de technische systeemtest van applicatietoepassingen. Daarnaast geef je vorm aan webpagina’s en applicaties, stel je gebruikersdocumentatie op en verleen je ondersteuning bij het oplossen van productiefouten. Tevens ben je verantwoordelijk voor het samenstellen en onderhouden van de applicatie c.q.

Bekijk vacature »

Senior DevOps-ontwikkelaar eIDAS

Functie­omschrijving Burgers en bedrijven veilig en betrouwbaar digitaal toegang geven tot diensten en producten van het ministerie van Economische Zaken en Klimaat. Als senior DevOps-ontwikkelaar bouw je daar letterlijk aan mee. En dat doe je bij DICTU: een van de grootste en meest vooruitstrevende ICT-dienstverleners van de Rijksoverheid. Jij werkt mee aan de doorontwikkeling van eIDAS, dat staat voor Electronic IDentification Authentication and trust Services. Deze koppeling maakt de grensoverschrijdende authenticatie op overheidswebsites binnen de Europese Unie mogelijk. Het ministerie van Economische Zaken en Klimaat heeft één moderne toegangspoort voor zijn diensten en inspecties. Enkele daarvan zijn dankzij eIDAS inmiddels

Bekijk vacature »

Technisch Ontwerper / Applicatie Ontwikkelaar

Technisch Ontwerper / Applicatie Ontwikkelaar Actief Wat ga je doen? Als Technisch Ontwerper / Applicatie Ontwikkelaar kom je te werken bij onze gerenommeerde klanten op projecten of opdrachten van omvang en formaat. Je bent verantwoordelijk voor het omzetten van functionele specificaties naar een technisch ontwerp, het ontwerp van programmaspecificaties voor toepassingen, de realisatie van (gewijzigde) programmaonderdelen en databestanden van toepassingen en de technische systeemtest van applicatietoepassingen. Daarnaast geef je vorm aan webpagina’s en applicaties, stel je gebruikersdocumentatie op en verleen je ondersteuning bij het oplossen van productiefouten. Tevens ben je verantwoordelijk voor het samenstellen en onderhouden van de applicatie c.q.

Bekijk vacature »

Technisch Ontwerper / Applicatie Ontwikkelaar

Technisch Ontwerper / Applicatie Ontwikkelaar Actief Wat ga je doen? Als Technisch Ontwerper / Applicatie Ontwikkelaar kom je te werken bij onze gerenommeerde klanten op projecten of opdrachten van omvang en formaat. Je bent verantwoordelijk voor het omzetten van functionele specificaties naar een technisch ontwerp, het ontwerp van programmaspecificaties voor toepassingen, de realisatie van (gewijzigde) programmaonderdelen en databestanden van toepassingen en de technische systeemtest van applicatietoepassingen. Daarnaast geef je vorm aan webpagina’s en applicaties, stel je gebruikersdocumentatie op en verleen je ondersteuning bij het oplossen van productiefouten. Tevens ben je verantwoordelijk voor het samenstellen en onderhouden van de applicatie c.q.

Bekijk vacature »

Technisch Ontwerper / Applicatie Ontwikkelaar

Technisch Ontwerper / Applicatie Ontwikkelaar Actief Wat ga je doen? Als Technisch Ontwerper / Applicatie Ontwikkelaar kom je te werken bij onze gerenommeerde klanten op projecten of opdrachten van omvang en formaat. Je bent verantwoordelijk voor het omzetten van functionele specificaties naar een technisch ontwerp, het ontwerp van programmaspecificaties voor toepassingen, de realisatie van (gewijzigde) programmaonderdelen en databestanden van toepassingen en de technische systeemtest van applicatietoepassingen. Daarnaast geef je vorm aan webpagina’s en applicaties, stel je gebruikersdocumentatie op en verleen je ondersteuning bij het oplossen van productiefouten. Tevens ben je verantwoordelijk voor het samenstellen en onderhouden van de applicatie c.q.

Bekijk vacature »

Technisch Ontwerper / Applicatie Ontwikkelaar

Technisch Ontwerper / Applicatie Ontwikkelaar Actief Wat ga je doen? Als Technisch Ontwerper / Applicatie Ontwikkelaar kom je te werken bij onze gerenommeerde klanten op projecten of opdrachten van omvang en formaat. Je bent verantwoordelijk voor het omzetten van functionele specificaties naar een technisch ontwerp, het ontwerp van programmaspecificaties voor toepassingen, de realisatie van (gewijzigde) programmaonderdelen en databestanden van toepassingen en de technische systeemtest van applicatietoepassingen. Daarnaast geef je vorm aan webpagina’s en applicaties, stel je gebruikersdocumentatie op en verleen je ondersteuning bij het oplossen van productiefouten. Tevens ben je verantwoordelijk voor het samenstellen en onderhouden van de applicatie c.q.

Bekijk vacature »

Technisch Ontwerper / Applicatie Ontwikkelaar

Technisch Ontwerper / Applicatie Ontwikkelaar Actief Wat ga je doen? Als Technisch Ontwerper / Applicatie Ontwikkelaar kom je te werken bij onze gerenommeerde klanten op projecten of opdrachten van omvang en formaat. Je bent verantwoordelijk voor het omzetten van functionele specificaties naar een technisch ontwerp, het ontwerp van programmaspecificaties voor toepassingen, de realisatie van (gewijzigde) programmaonderdelen en databestanden van toepassingen en de technische systeemtest van applicatietoepassingen. Daarnaast geef je vorm aan webpagina’s en applicaties, stel je gebruikersdocumentatie op en verleen je ondersteuning bij het oplossen van productiefouten. Tevens ben je verantwoordelijk voor het samenstellen en onderhouden van de applicatie c.q.

Bekijk vacature »

Snelle Jaap

Snelle Jaap

09/04/2018 13:08:03
Quote Anchor link
Ik heb een site met producten die binnen categorieeen hangen. Deze categorieen kunnen ook weer binnen subcategorieen hangen. In een zijmenu met alle toplevel categorieen heb ik een cijfer staan per categorie die het aantal producten laat zien binnen deze categorie.

https://i.stack.imgur.com/BJVN4.png

Dit telt alleen de producten binnen de toplevel categorie. Terwijl er ook producten binnen subcategorieen kunnen staan, deze worden niet meegeteld.

Mijn structuur is nu als volgt:

categorie:
id - categorie id
parent_id - id van parent categorie (topcategory is altijd 1), dit is hetzelfde als het id van zijn parent categorie.


artikel(product)
id - id van het product
catid - id van de categorie waar hij onder hangt (zelfde als id van de categorie)


Dus als mijn data er zo uitziet:

categorie - wastafels - 2 producten
subcategorie - wastafelssub - 5 producten
subsubcategorie - wastafelssubsub - 2 producten

Met mijn huidige code krijg ik naast Wastafels een 2, maar ik zou willen dat hij alles optelt, dus dat er 9 komt te staan.

Dit is nu mijn 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
//Haal alle toplevel categorieen op
$pcat             = "SELECT * FROM `snm_categories` WHERE published = 1 and level = 1 and id NOT IN (1) order by rgt ";
$pcatcon          = $conn->query($pcat);
$catids           = '';
while ($pcat      = $pcatcon->fetch_assoc()){
    $catids[] = $pcat['id'];
    // Alle producten binnen bovenstaande categorieen
    $aantal         = "SELECT DISTINCT id FROM `snm_content` WHERE catid = ".$pcat['id']." and state = 1";
    $aantalcon      = $conn->query($aantal);
    $aantal         = $aantalcon->fetch_assoc();

    if(is_null($aantal)){
        $totaal = '';
    }else{
        $totaal = $aantalcon->num_rows;
    }
    if($totaal != 0){
        $amount = '('.$totaal.')';
    }else{
        $amount = $totaal;
    }

    $productcatoverzicht .= '
    <li class="cat-item"><a href="'.$pcat['alias'].'">'.$pcat['title'].'</a><span class="count">'.$amount.'</span></li>';
}
echo productcatoverzicht;


Moet ik dit net als mijn menu code recursief oplossen? Mijn menu code ziet er zo uit:

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
<?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
    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);
    ?>


Hoe kan ik dit het beste oplossen?
 
PHP hulp

PHP hulp

26/09/2020 00:51:45
 
Ben van Velzen

Ben van Velzen

09/04/2018 13:41:07
Quote Anchor link
Op exact dezelfde manier als buildMenu werkt. Gewoon data in 1 keer ophalen en in PHP verwerken. Als je een wat geavanceerdere database gebruikte kon je een recursieve query schrijven maar dat is hier niet van toepassing. Overigens, waarom noem je je resultsets $xxxcon? Het is geen verbinding maar een resultaat.
Gewijzigd op 09/04/2018 13:41:53 door Ben van Velzen
 
Ivo P

Ivo P

09/04/2018 16:35:00
Quote Anchor link
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
    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";


wat doet die group by daar?
Je gebruikt nergens een aggregatie functie (zoals sum(), count()) dus waarom dan group by?
En als je dat al toepast: dan staan achter group-by alle kolommen die niet een aggregatie functie. Dus gewoon alle kolommen in jouw geval, dus netto zou dat niets doen.
 
Thomas van den Heuvel

Thomas van den Heuvel

09/04/2018 16:42:57
Quote Anchor link
Wat @Ben zegt, de recursie werkt precies hetzelde, alleen het werk wat je verzet tijdens een iteratie (stap) is anders.

In feite is het zaak dat je een optelsom van de "children" maakt.

Nu heb je e.e.a. als volgt gestructureerd:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
<?php
while($menu = $menuconn->fetch_assoc())
{

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

?>

(waarbij "parents" eigenlijk "children" zou moeten zijn?)
Maar je zou het ook als volgt kunnen doen:
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
<?php
// @todo maak hier een onzichtbaar root-element, in wezen initialiseer je $menuItems hier
$menuItems[0] = array(
    'data'     => array(/* zet hier bijvoorbeeld een label in */),
    'parent'   => false,
    'children' => array(),
);

// haal hier *alle* items in de goede volgorde op, inclusief root-elementen
while($menu = $menuconn->fetch_assoc())
{

    $parentId = $menu['parent_id'] === NULL ? 0 : $menu['parent_id'];
    $menuItems[$menu['cat_id']] = array(
        'data'     => $menu,
        'parent'   => $parentId,
        'children' => array(),
    );

    // voeg item toe als child van parent
    $menuItems[$parentId]['children'][] = $menu['cat_id'];
}

?>

Hierbij helpt het als je dus in de query de root-elementen toevoegt, en hierboven nog een soort van "onzichtbare" root zet waaraan alle root-elementen verbonden zijn. Op die manier krijg je een echte boom (met één hoofd-root) waar je makkelijk doorheen kunt lopen.
Gewijzigd op 09/04/2018 16:49:39 door Thomas van den Heuvel
 
Snelle Jaap

Snelle Jaap

09/04/2018 16:51:57
Quote Anchor link
Die onzichtbare root is er eigenlijk al, alle topcategorieen hebben parent_id 1, die 1 is de categorie ROOT in mijn database. Ik ga hier is wat mee proberen, zelf kwam ik op dit uit (niet werkend en waarschijnlijk nog vol fouten):

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
function getProdsInCat($cat, $conn){
        global $prods;
        // Tell alle producten binnen de doorgegeven categorie
        $countproducts    = "SELECT COUNT(`id`) FROM `snm_content` WHERE `catid` = '".$cat."'";
        $countproductscon = $conn->query($countproducts);
        $countproducts    = $countproductscon->fetch_assoc();

        // Haal alle categorieen op waar parent_id gelijk is aan het meegestuurde id
        $countcats       = "SELECT * FROM snm_categories WHERE parent_id = '".$cat."'";
        $countcatscon    = $conn->query($countcats);
        while($countcats = $countcatscon->fetch_assoc()){
            getProdsInCat($countcats['id'],$conn);
        }
    }
    // Loop alle categorieen en stop de functie in de loop zodat deze alle ids doorgeeft aan de functie
    $allcats = "SELECT * FROM snm_categories WHERE published = 1";
    $allcatsconn = $conn->query($allcats);
    while($allcats = $allcatsconn->fetch_assoc()){
      $allprods = getProdsInCat($allcats['id'], $conn);
    }
 
Thomas van den Heuvel

Thomas van den Heuvel

09/04/2018 17:45:36
Quote Anchor link
Misschien heb ik het niet goed uitgelegd. Het is hier weer een kwestie van problemen opsplitsen denk ik.

Eerst bouw je een datastructuur in de vorm van een boom, en vervolgens laat je op deze boom recursieve functies los. Op het moment dat je voldoende informatie in deze datastructuur hebt zitten kun je daarmee de dataverrijking uitvoeren (bijvoorbeeld het tellen van het totaal aantal children van een categorie) zonder verdere tussenkomt van een database.
 
Ward van der Put
Moderator

Ward van der Put

09/04/2018 17:53:29
Quote Anchor link
Thomas van den Heuvel op 09/04/2018 17:45:36:
Het is hier weer een kwestie van problemen opsplitsen denk ik.

Eens. En het eerste probleem is dan: wáárom moet er überhaupt een telling in een menu worden getoond? ;-)
 
Snelle Jaap

Snelle Jaap

11/04/2018 15:23:03
Quote Anchor link
Ward van der Put op 09/04/2018 17:53:29:
Thomas van den Heuvel op 09/04/2018 17:45:36:
Het is hier weer een kwestie van problemen opsplitsen denk ik.

Eens. En het eerste probleem is dan: wáárom moet er überhaupt een telling in een menu worden getoond? ;-)

Waarom niet?
 
Ramon van Dongen

Ramon van Dongen

12/04/2018 07:59:11
Quote Anchor link
Snelle Jaap op 11/04/2018 15:23:03:
Waarom niet?


Ah, nu komen we ergens. Door dit soort inhoudelijke vragen is het probleem snel opgelost :-)
 
Rob Doemaarwat

Rob Doemaarwat

12/04/2018 18:01:52
Quote Anchor link
Gewoon recursief doen:
- vanuit je "root" genereer je de sub-menus
- vanuit de sub-menus geef je naast de resulterende HTML ook het aantal items terug (en tel je die op bij de items in het menu zelf - en die geef je weer terug, enz).
 



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.