Menu klasse

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Junior Software Developer C# Verhuursector Verhuur

Samengevat: Wij ontwikkelen en leveren softwaresystemen voor de logistieke sector en de verhuursector. Ben jij geschikt als Junior Software Developer? Heb je ervaring met Delphi? Vaste baan: C# Software Developer Logistiek HBO €2.500 - €3.900 Deze werkgever is een software ontwikkelaar, gericht op software voor de logistieke sector. Deze werkgever heeft eigen producten ontwikkelen en leveren ook maatwerk. Ons bedrijf kent een boeiende en inspirerende werkomgeving met een open cultuur en mogelijkheden voor je verdere ontwikkeling. Bij bij hun werk je aan onze eigen bedrijfsapplicaties. Je ontwikkelt met ons de meest nieuwe software. Wij blinken uit als het gaat om

Bekijk vacature »

PHP Software Developer

Functie omschrijving PHP Software Developer gezocht! Voor een organisatie in de regio Zeist die zich bezighoud met het verbeteren van de medicatieveiligheid zoeken wij een Software Developer. In deze functie zijn wij op zoek naar een slimme en enthousiaste Developer die interesse heeft in farmacie, logistiek en ICT. Daarnaast beschik je over een goed analytisch vermogen en ben je van nature gestructureerd en resultaatgericht. Je moet in deze functie daadkrachtig, flexibel en communicatief goed zijn. Je verantwoordelijkheden bestaan uit: Object georiënteerd programmeren; Werken in een scrumteam aan de ontwikkeling van een medicatiebewakingssysteem; Meedenken over de mogelijkheden en onmogelijkheden van projecten;

Bekijk vacature »

.NET Developer

Functie omschrijving Ervaren .NET Developer gezocht! Wij zoeken een ervaren .NET developer die aan de slag gaat voor een softwarebedrijf in de regio Rhenen. In deze rol ben jij zowel zelfstandig als in teamverband verantwoordelijk voor het ontwikkelen en verbeteren van bestaande producten. Daarnaast houdt jij je bezig met de nieuwbouw van websites, webapplicaties en mobiele applicaties die zowel intern als extern gebruikt worden. Je werkt hierbij nauw samen met andere developer, productmanagers en product specialisten om mooie producten te creëren. Bedrijfsprofiel Waar kom je te werken? Je komt te werken voor snelgroeiende softwareleverancier en allround dienstverlener. Klanten van deze

Bekijk vacature »

Medior Java developer

Wat je gaat doen: Of beter nog, wat wil jij doen? Binnen DPA GEOS zijn we dan ook op zoek naar enthousiaste Java developers om ons development team te versterken. Als Java developer werk je in Agile/Scrum teams bij onze klanten en daarbij kun je eventueel ook andere ontwikkelaars begeleiden in het softwareontwikkelproces. Verder draag je positief bij aan de teamgeest binnen een projectteam en je kijkt verder dan je eigen rol. Je gaat software 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

Bekijk vacature »

.NET Developer Azure

Dit ga je doen Het ontwerpen en bouwen van diverse applicaties (C#, ASP.NET, MVC); Het ontwikkelen van Webservices (WCF); Het meewerken aan de transitie naar Azure; Het samenwerken met collega's binnen een Scrumteam en meedenken over de User Stories; Het bouwen van unittesten; Meedenken over nieuwe tooling, ontwikkelingen en technologieën in de markt. Hier ga je werken Je komt te werken bij een organisatie die verantwoordelijk is voor de ontwikkeling van verschillende portalen. Deze portalen worden gebruikt door diverse partijen en jouw taak is om ervoor te zorgen dat deze optimaal functioneren. Je wordt onderdeel van een Scrumteam en werkt

Bekijk vacature »

Junior Low-code ontwikkelaar gezocht omgeving Arnh

Bedrijfsomschrijving Wij zijn een dynamisch IT-bedrijf dat zich richt op het stroomlijnen van bedrijfsprocessen en het creëren van ondersteunende applicaties. Onze kracht ligt in het combineren van zakelijk inzicht met IT-expertise via gestroomlijnde procesontwerpen en wendbare applicatieontwikkeling met behulp van Low-code technologieën. Als jonge professional krijg je de kans om samen te werken met een team van 15 deskundige collega's, verspreid over nationale en internationale locaties. We bieden je een leerzame omgeving waar je je vaardigheden kunt ontwikkelen en groeien in je rol als Low-code ontwikkelaar. Word jij onze nieuwe Junior Low-code Ontwikkelaar (OutSystems)? Versterk ons team en draag bij

Bekijk vacature »

PHP Developer

Dit ga je doen Je werkt nauw samen met het websitebureau aan de ontwikkeling en optimalisering van het internationale platform; Je ziet nieuwe webshops op en voert optimalisaties door; Je bouwt aan technische, functioneel en commercial resultaat; Je vindt het leuk om zelfstandig binnen een internationale organisatie te werken, maar krijgt ook energie om samen met collega's te werken. Hier ga je werken Voor een bedrijf in de regio Rotterdam zijn wij opzoek naar een PHP Developer. Je wordt onderdeel van het communicatieteam en gaat je bezighouden met het optimaliseren van de website van dit internationale bedrijf. Je schakelt veel

Bekijk vacature »

Full stack ontwikkelaar Laravel, Vue.js

Functie Als ontwikkelaar binnen deze organisatie hou jij je voornamelijk met lopende projecten voor de verschillende klanten. Zo bouw je de ene dag aan prijsschifting systemen en de andere dag onderzoek je crawlers en stel je ze zo in dat de data goed binnen komt binnen het systeem. Daarnaast bouw je mee aan dashboards en ben je dus constant bezig met het verbeteren van het platform. Er is een vaste werkwijze, zo werken ze met Trello kaarten en onderverdelen ze deze aan het begin van iedere week onder de developers. Dit wordt door de lead developer gedaan, maar in samenspraak

Bekijk vacature »

Front-end developer - working on software for arou

Functie They have recently started looking for an experienced Front-end (mobile/app) developer. Because of the short lines within the team, they are also looking for someone who can communicate with the service desk, sales and support for technical questions. You will join their IT team consisting of about 10 colleagues divided over two teams in rooms opposite each other. Half of these are involved in their front-end. You will work together with, among others, the Architect, 1 senior, 1 junior and there is a Team Leader. In terms of technology, they work with a unique tech-stack, particularly because of the

Bekijk vacature »

Starter/junior Magento developer gezocht!

Functie Je komt te werken in een zelfsturend team waarin vertrouwen voorop staat en inbreng en ideeën worden gewaardeerd. Ook staat innovatie centraal. Ze bieden jou de mogelijkheid om jezelf door te ontwikkelen. Denk hierbij aan cursussen en een persoonlijk ontwikkelplan. Je komt terecht in het team van momenteel 4 (ervaren) collega’s en zal meewerken aan de doorontwikkeling en nieuwbouw van de Magento platformen van meerdere opdrachtgevers volgens Agile/Scrum. Denk hierbij aan nieuwe functionaliteiten, UX en koppelingen met verschillende back-end systemen. Als starter/junior developer zul je direct begeleid worden door een senior uit het team. Het is van belang dat

Bekijk vacature »

Backend Developer Integraties API HBO REST

Samengevat: Deze werkgever is een IT-consultancy. Wil jij werken als Backend Developer Integraties? Heb jij kennis van gangbare berichtformaten? Vaste baan: Backend Developer Integraties API HBO €3.100 - €4.400 Zij bieden innovatieve oplossingen die bedrijven efficiënter en wendbaarder maken, waardoor onze klanten zich net zo snel kunnen ontwikkelen als de business van hen vraagt. Bij bij hun werk je aan onze eigen bedrijfsapplicaties. Je ontwikkelt met ons de meest nieuwe software. Wij blinken uit als het gaat om de inzet van technologie. Deze werkgever staat open voor elke nieuwe trend. Onze systemen zijn groot en ingewikkeld. Hou jij van diepgang

Bekijk vacature »

Back-end Developer (Permanent position with the em

Bedrijfsomschrijving Dutch specialist in technical installation materials. Functieomschrijving Purpose of the position: Our client is looking for a Back-end Developer who, together with the rest of the energetic and dynamic team, is responsible for the development and management of the website. This not only concerns the development and management of the current website, but also the development of a new Headless Commerce Platform to keep the customer's website Future proof. Within the IT department, there is a real DevOps culture and the commerce team is at the forefront and tries to implement continuous improvements. Most important tasks: ï‚· Designing and

Bekijk vacature »

Medior Java developer

Wat je gaat doen: Of beter nog, wat wil jij doen? Binnen DPA GEOS zijn we dan ook op zoek naar enthousiaste Java developers om ons development team te versterken. Als Java developer werk je in Agile/Scrum teams bij onze klanten en daarbij kun je eventueel ook andere ontwikkelaars begeleiden in het softwareontwikkelproces. Verder draag je positief bij aan de teamgeest binnen een projectteam en je kijkt verder dan je eigen rol. Je gaat software 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

Bekijk vacature »

Backend Developer PHP Laravel SaaS

Dit ga je doen Het ontwikkelen van nieuwe features die bijdragen aan de groei van de klanten van de organisatie; Je denkt mee over nieuwe innovaties, features en verbeteringen in de applicatiearchitectuur; Je draagt bij aan de continue ontwikkeling van jouw team doordat je elke dag streeft naar het verbeteren van jouw eigen prestaties; Je neemt actief deel aan Scrum meetings en de Backend Guild. Hier ga je werken Voor een snel groeiend bedrijf, in de regio Nieuw Vennep, zijn wij opzoek naar een ervaren Backend Developer. De organisatie is actief in de e-commercebranche en ontzorgt haar klanten middels een

Bekijk vacature »

.NET Developer te Naarden

Bedrijfsomschrijving Voor mijn klant ben ik op zoek naar een .NET Developer om het huidige team te komen versterken. Deze organisatie bevindt zich in de logistieke sector, en zij hebben een eigen ERP systeem ontwikkeld dat zij inzetten ter optimalisatie van de logistieke processen van haar eindklanten. Deze organisatie bestaat inmiddels al ruim 20 jaar, waarbij zij een duidelijke missie hebben, namelijk: het werk van de eindklant makkelijker maken door de systemen die zij leveren. Ze werken over heel de wereld, wat deze organisatie een echte internationale speler maakt. Binnen de organisatie kenmerken ze zich door een dynamische en professionele

Bekijk vacature »
Tom Swinkels

Tom Swinkels

04/03/2012 21:30:06
Quote Anchor link
Beste Phpers,

Ik wil een menu klasse gaan schrijven, de bedoeling is dat het menu uit de database komt. Er kunnen ook sub-menu's zijn.

Nu zat ik zelf te denken aan een menu klasse.

klasse Menu:

-setName($name)
-setUrl($url)
-setParentId($parentid)
-setId()
-getName() (array)
-getUrl() (array)
-getParentId (array)
-getId() (array)

klasse MenuMapper:

-getMenu() (haalt het menu uit de database en maakt de klasse menu aan)

Ik vroeg me af of dit een goede opzet is, en hoe ik verder alle gets bij elkaar kan voegen aangezien alles los word opgeslagen van 1 menu item?
 
PHP hulp

PHP hulp

27/04/2024 03:45:53
 
Wouter J

Wouter J

04/03/2012 21:54:45
Quote Anchor link
Ik zou het nog 1 keer verder verdelen en ook een Menu_item klasse gebruiken:

Menu_list
# items = array()
# rol = ''
+ constructor( array $items = array(), $rol = 'primary' )
+ addItem( $item )
+ removeItem( $id )

Menu_item
# url
# name
+ constructor( $name, $url )
+ setName( $name )
+ setUrl( $url )
+ getName( $name )
+ getUrl( $url )
+ __toString()

Dan kun je ook veel makkelijker submenu's maken:
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
$menu
= new Menu_list();

// normale menu items
$menu->addItem( new Menu_item('Home', '/home') );
$menu->addItem( new Menu_item('About', '/about') );

// submenu's
$menu->addItem( new Menu_list(array(
  new
Menu_item('Foo', '/category/1/foo'),
  new
Menu_item('Bar', '/category/2/bar'),
  new
Menu_item('Lorem', '/category/3/lorem'),
)) );

?>
 
Tom Swinkels

Tom Swinkels

04/03/2012 22:02:30
Quote Anchor link
Oke, dit is opzicht wel duidelijk maar je kunt natuurlijk ook alles in een array gooien? En daarna de array verdelen/sorteren? ParentId = 0 wil namelijk zeggen dat het een menu is, wanneer het geen 0 is zal dat het id van het hoofd menu zijn.

Hoe wil jij het op jou manier uit de database halen? Want aan jou voorbeeld kan ik niet zien bij welk menu de sub-items horen?

Verder geef jij in je voorbeeld $name en $url mee aan de __contruct, waarom heb je dan nog een setName() en setUrl() methode?
 
Wouter J

Wouter J

04/03/2012 22:08:33
Quote Anchor link
Quote:
dit is opzicht wel duidelijk maar je kunt natuurlijk ook alles in een array gooien? En daarna de array verdelen/sorteren?

Ja, maar dan moet je alsnog werken met een menu item klasse. Want je hebt nu gewoon properties die niet bij het menu object horen. Als id, parent_id, url, name. Dat zijn allemaal eigenschappen van een menu item en niet van een menu.
Dus als je alles in een array stopt heb je minder OO en wordt de klasse meer een verzameling functies (wat ook niet slecht is, maar dan is het geen OO meer).

Quote:
Hoe wil jij het op jou manier uit de database halen? Want aan jou voorbeeld kan ik niet zien bij welk menu de sub-items horen?

Dat is ook een probleem waaraan ik zat te denken. Je zou een Menu_item Mapper moeten maken, maar misschien ook een Menu_list Mapper.

Quote:
Verder geef jij in je voorbeeld $name en $url mee aan de __contruct, waarom heb je dan nog een setName() en setUrl() methode?

De naam en de url zijn eigenschappen die je nodig hebt voor het correct werken van een klasse. Vandaar dat ze aan de constructor meegegeven worden.
Maar omdat in OO alles draait om flexibiliteit zitten er ook nog aparte setters in, zodat je halverwege het script de url/name kunt wijzigen.
 
Tom Swinkels

Tom Swinkels

04/03/2012 22:25:41
Quote Anchor link
Ok, maar een menuItem klasse spreekt mij niet zo aan. Een menuList klasse wel.
Wat zou je verder met een menu klasse van kunnen doen?

Verder weet ik ook nog niet goed hoe ik dit in OO moet oplossen met de sub items. Misschien dat het helpt om de manier te delen hoe ik het zonder OO deed. Misschien dat jullie dan weten hoe ik het in OO op de beste manier kan 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
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
<?php
    public function getMenu($i_parentid)
    {

            $string = null;
            $result = $this->_db->prepare("SELECT
                                                    webn_name,
                                                    webn_url,
                                                    webn_parentid,
                                                    webn_id
                                            FROM
                                                    web_navigation
                                            WHERE
                                                    webn_state = 1
                                            AND
                                                    webn_parentid = ?
                                            ORDER BY
                                                    webn_order
                                            ASC
                                            "
);
            $result->execute(array($i_parentid));
            $list = $result->fetchAll();

            foreach($list as $array)
            {

                $string[] = $array;
            }

            return $string;
    }

                $getMenu = $index->getMenu(0);
                if(count($getMenu) > 0)
                {

                    foreach($getMenu as $menu)
                    {

                        echo '<li class="menu"' . ($menu['webn_url'] == $config->getUrl(1) ? ' class="select"' : '') . '>';
                        echo ($menu['webn_url'] != '' ? '<a href="' . SITE_PATH . $menu['webn_url'] . '/">' : '');
                        echo $config->replaceMessage($menu['webn_name']);
                        echo ($menu['webn_url'] != '' ? '</a>' : '');
                        
                        $getSubMenu = $index->getMenu($menu['webn_id']);
                        if(count($getSubMenu) > 0)
                        {

                            echo '<ul class="menusub">';
                            foreach($getSubMenu as $sub)
                            {

                                echo '<li class="menusub"' . ($sub['webn_url'] == $config->getUrl(1) ? ' class="select"' : '') . '>';
                                echo ($sub['webn_url'] != '' ? '<a href="' . SITE_PATH . $sub['webn_url'] . '/">' : '');
                                echo $config->replaceMessage($sub['webn_name']);
                                echo ($sub['webn_url'] != '' ? '</a>' : '');
                                echo '</li>';
                            }

                            echo '</ul>';
                        }

                        echo '</li>';
                    }
                }

                else
                {
                    echo 'ERROR: No menu items';
                }

                ?>


Toevoeging op 05/03/2012 17:54:51:

Als ik het zo zelf nog eens bekijk denk ik nu aan de volgende klasse:

-MenuListMapper
-getMenu($parentId)

-MenuList
-setName($name)
-setUrl($url)
-setParentId($parentId)
-setId($id)
-getName()
-getUrl
-getParentId()
-getId()

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
$menuListMapper = new MenuListMapper($db);
$menuList = $menuListMapper->getMenu(0);

$menuListSub = $menuListMapper->getMenu('PARENT_ID');


Of zou ik twee methode's moeten maken? Menu() MenuSub()?
Tocht ben ik er nog niet helemaal over uit. Hoop dat jullie mij beter kunnen helpen!
 
Mark Kazemier

Mark Kazemier

07/03/2012 12:27:44
Quote Anchor link
Ik zou persoonlijk net zoals Wouter J al zegt werken met een Menu en een MenuItem klasse. Een MenuItem is namelijk echt iets heel anders en deze zal ook eigen functionaliteit krijgen.

Het ophalen van het menu zou ik doen met een MenuRepository waar je gewoon direct het hele menu of het menu vanaf een bepaald subitem op kan vragen. Het liefst heb je niet dat de Menu en MenuItem klassen weten dat ze opgeslagen kunnen worden en hoe dit gebeurt. Dat maakt het later ook eenvoudiger om een XML opslag techniek te gebruiken bv.

Quote:
Maar omdat in OO alles draait om flexibiliteit zitten er ook nog aparte setters in, zodat je halverwege het script de url/name kunt wijzigen.


Zeer slecht argument. Een setter wel of niet definiëren heeft niets met flexibiliteit te maken. Sterker nog ik zou een setter alleen definiëren als ik hier een heel goede reden voor had. Het druist namelijk in tegen het OOP principe van het afschermen van data. Je doet dat op zo'n moment namelijk nog maar gedeeltelijk.

De meeste transities van state van een object zal je binnen het eigen object willen laten plaatsvinden. In een eigen methode. Op het moment dat je een setter maakt, geef je deze "macht" af aan andere klassen. Iedereen kan opeens deze state veranderen. Natuurlijk kan de setter wel logica bevatten, maar dit doet deze eigenlijk nooit.
 
Kees Schepers

kees Schepers

07/03/2012 12:49:31
Quote Anchor link
Het is een heeeeel oud script van me maar misschien heb je er wat aan:

http://www.phphulp.nl/php/script/php-algemeen/menu-ulli-structuur/1149/
 
Kris Peeters

Kris Peeters

07/03/2012 14:27:24
Quote Anchor link
Je hebt nog niets geschreven; je hebt een voorstel en vraagt of je nog "goe bezig" bent, of dit de richting is waarin je tijd en moeite wil investeren; juist?

Indien je bereid bent wat extra moeite te doen, kan je de structuur ook anders regelen.
MySQL heeft een systeem waarmee je gegevens kan ordenen, in een hiërarchische structuur.

Je kan dan oneindig complex (nu ja, ...) items in een hiërarchie steken, zonder op voorhand te moeten weten hoe diep de structuur moet gaan.

In jouw geval kan je dus een submenu hebben die zelf een aantal items hebben die submenu's hebben.
Tja, zoals dat dus het geval is bij menu's van programma's op je pc.

Hier vind je uitleg:
http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/

Dus nog eens duidelijk maken: hiervoor zal je wat tijd moeten maken om het onder de knie te krijgen en waarschijnlijk is het overkill voor wat je nu nodig hebt.
Indien je het de moeite niet vind, ben ik de eerste om dit goed te begrijpen, doe dan maar voort zoals je bezig bent.
 
Tom Swinkels

Tom Swinkels

07/03/2012 14:45:11
Quote Anchor link
@Mark: Ik kan het menu (database) toch ook opvragen in de userMapper() klasse? Die heb ik later ook nodig voor het wijzigen?

@Kees: Bedankt, maar op die manier genereer je de HTML en niet de menu items zelf.

@Kris: Is het verstandig om dat met MySQL te doen? Ik ben dat ook nog nooit eerder tegen gekomen dus vraag mezelf af of het wel verstandig is om dat toe te passen.

--

Verder heb ik nog niet veel duidelijkheid over hoe ik de opbouw zou kunnen doen in OO. Hoe weet ik straks welk sub-item bij welk item hoort? Is het idee van de getters en setters wel goed?
 
Mark Kazemier

Mark Kazemier

07/03/2012 14:51:20
Quote Anchor link
Uhm, volgens mij begrijp je het helemaal verkeerd Tom.
Allereerst, wat heeft een menu met de user te maken? Dus waarom zou je dat opeens uit een UserMapper halen?

Dan de structuur die wij voorstellen zijn twee klassen:
- Menu
- MenuItem

Een menu is het hele menu. Het MenuItem is een los item uit het menu.
Voorbeeldje:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
Hoofdmenu
- Home
- Inloggen
- Forum
- Blog


Het hoofdmenu is nu een Menu, dus Menu object. De items Home, Inloggen, Form en Blog zijn nu MenuItems.
 
Tom Swinkels

Tom Swinkels

07/03/2012 15:00:11
Quote Anchor link
@Mark: Ik bedoelde MenuMapper() i.v.m UserMapper().
De klasse Menu en MenuItem hoeven niet te weten dat een menu uit de database komt daar zorgt de MenuMapper() voor.

Verder maakt de MenuMapper() het Menu() en MenuItem() object aan wanneer het menu uit de database word gehaald?

Begrijp ik het nu een beetje?
 
Kris Peeters

Kris Peeters

07/03/2012 15:09:16
Quote Anchor link
Mijn punt gaat om de manier waarom je je gegevens op zijn plaats zet in de hiërarchie.

Jij gaat uit van 1 top-menu, elk top-menu kan 1 generatie submenu's bevatten.
In dit geval kan je doen wat jij doet: het volstaat dat een submenu zijn parent (id) bijhoudt.

Trouwens, al eens nagedacht over de volgorde van de items van een submenu? Stel dat je (sub)item 5 eigenlijk liever op de tweede plaats hebt; hoe maak je dat duidelijk in de database?


Het systeem dat ik voorstel werkt niet met een parent-veld. Elk item heeft een left-waarde en een right-waarde (steeds een integer).
Elke left-waarde of right-waarde komt slechts 1 keer voor.
Met die waarden heeft elk item ondubbelzinnig zijn plaats in de structuur.

Dat laat gelijk welke boomstructuur toe. Zie vooral:
Afbeelding

Waar dit artikel over gaat, is dus een reeks sql statements die heel dit systeem regelen.
bv. indien right - left = 1 => dan weet je dat het een "leaf node" is: een blad, een eindpunt (geen subitems).
Je hebt statemants om - een hele tak te verhuizen naar een andere node, items van plaats te wisselen, ...

Het zit goed in mekaar; het werkt; het laat jou veel mogelijkheden toe.
... maar dan wel meer dan je vraagt; je moet zelf bepalen of het de moeite waard is.
Gewijzigd op 07/03/2012 15:11:11 door Kris Peeters
 
Tom Swinkels

Tom Swinkels

07/03/2012 15:22:17
Quote Anchor link
@Kris: Daar wilde ik een sort column voor maken.
Ik vind het idee van je wel erg interessant, enkel snap ik het nog niet helemaal "indien right - left = 1" geen sub-items.
Wanneer heeft het dan wel sub-items?
En hoe weet ik nu dat TELEVISIONS bijvoorbeeld een sub-item is?
 
Kris Peeters

Kris Peeters

07/03/2012 15:38:38
Quote Anchor link
Kijk eens naar "Portable electronics" (image).
Left: 10; right: 19.

Er zijn 8 getallen tussen 10 en 19, dus je weet dat er in totaal 4 nodes staan onder "Portable electronics".

Stel dat je de hele tak onder "Portable electronics" wil verwijderen. Dan moet je dus alles verwijderen met een left en right tussen de waarden 10 en 19.
Daarna moet het gat terug gevuld worden: alle getallen groter dan 10 moeten met 8 verminderen.

"Portable electronics" wordt dan: left: 10; right: 11.
Electronics wordt dan: left: 1; right 12

Zo is er dus een procedure voor alle mogelijke dingen die je met een boomstructuur kan uitsteken. En je moet die zelf niet uitvinden: die staan in het artikel
Gewijzigd op 07/03/2012 15:39:32 door Kris Peeters
 
Tom Swinkels

Tom Swinkels

07/03/2012 16:25:04
Quote Anchor link
@Kris: Het word nu een stuk duidelijker.
Enkel ben ik het nog niet helemaal eens over de manier, wanneer je een nieuw sub-item krijgt moeten alle nummertjes aangepast worden?
Gebruik je deze manier zelf ook voor een menu op te halen?
 
Kris Peeters

Kris Peeters

07/03/2012 17:11:27
Quote Anchor link
Elke verandering van de structuur zorgt er inderdaad voor dat meerdere records worden aangepast; enkel de velden lft en rgt (left en right zijn gereserveerde woorden), wel te verstaan.

Dit lijkt een vreemde manier van doen, maar het werkt.

Google eens "hierarchical mysql". Alle zoekresultaten vertellen het zelfde verhaal.
Dit artikel stond nog op de site van mysql zelf.
(Ik bedoel maar ... don't take my word for it, zie eens wat de rest van de wereld er van vindt; ik heb dit niet bedacht.)

De echte vraag is: is het de moeite waard voor wat je maar nodig hebt?

Dit soort dingen kan je vaak best eerst apart testen. Los van waar je echt mee bezig bent.

Het is al een aantal jaar geleden dat ik dit echt nog gebruikte. Toen was de noodzaak ook groter; de structuur was complexer dan de vraag die jij stelt.
 
Tom Swinkels

Tom Swinkels

07/03/2012 17:39:13
Quote Anchor link
@Kris: Ik zal eens google, het moet natuurlijk wel makkelijk uit te breiden zijn naar sub-item/sub-item bijvoorbeeld. Op jou manier is dat weer een stuk makkelijker. Stel er komt een klant naar mij en zegt ik wil onder sub-menu01 nog een menu hebben.

Toevoeging op 07/03/2012 17:54:08:

Ik heb een mooi artikel gevonden op Pfz.nl -> http://www.pfz.nl/wiki/hierarchie-in-een-database/ ik ga daar eens even naar kijken!

Toevoeging op 07/03/2012 19:02:40:

Ik heb volgende artikel: http://netters.nl/artikelen/php-en-mysql/hierarchie-in-de-database/ lees ik dat "Het modified preorder tree traversel model" de beste oplossing is, omdat dit de snelste manier is.
Echter kan je ook gewoon een view maken, en hoef hij die view alleen aan te passen wanneer er iets gewijzigd word.
Toch vind ik die andere manier wel makkelijk, alleen kost het extra rekentijd bij het aanmaken en verwijderen van een item.

Toevoeging op 07/03/2012 21:04:56:

Ik ben het nu voor elkaar echter gaat er nog iets mis, de resultaten kloppen niet er worden bepaalde dingen niet afgesloten?
Ook klopt het resultaat niet aangezien cat01, cat02 en cat03 hoofd items zijn.

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
$resultUser = $db->prepare("SELECT node.name, COUNT(*) - 1 AS lvl
FROM menu AS node,
        menu AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt
GROUP BY node.lft, node.name
ORDER BY node.lft");
$resultUser->execute(array());
$listUser = $resultUser->fetchAll();

if(count($listUser) > 0)
{
    echo '<ul>';
    foreach($listUser as $i => $user)
    {
        echo '<li>
            '. $user['name'];
        if($listUser[$i+1]['lvl'] > $listUser[$i]['lvl'])
        {
            echo '<ul>';
        }
        elseif($listUser[$i+1]['lvl'] < $listUser[$i]['lvl'])
        {
            echo '</li>
                </ul>
            </li>';
        }
        else
        {
            echo '</li>';
        }
    }
    echo '</ul>';
}


Output:
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
<ul>
    <li>cat01
        <ul>
            <li>cat01A
                <ul>
                    <li>cat01B
                        <ul>
                            <li>cat01C1</li>
                            <li>cat01C2</li>

                                </ul>

                            </li>
                    <li>cat02</li>
                    <li>cat03
                        <ul>
                            <li>cat03A</li>

                                   </ul>

                            </li>
                </ul>


SQL

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
CREATE TABLE IF NOT EXISTS `menu` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(20) NOT NULL,
  `lft` int(11) NOT NULL,
  `rgt` int(11) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=9 ;

--
-- Gegevens worden uitgevoerd voor tabel `menu`
--

INSERT INTO `menu` (`id`, `name`, `lft`, `rgt`) VALUES
(1, 'cat01', 1, 10),
(2, 'cat01A', 2, 9),
(3, 'cat01B', 3, 8),
(4, 'cat01C1', 4, 5),
(5, 'cat01C2', 6, 7),
(6, 'cat02', 11, 12),
(7, 'cat03', 13, 16),
(8, 'cat03A', 14, 15);
Gewijzigd op 08/03/2012 02:04:30 door Tom Swinkels
 
Kris Peeters

Kris Peeters

08/03/2012 11:35:33
Quote Anchor link
Ik heb vroeger ondervonden dat het een goed idee is om altijd een root te hebben waar iedereen van afstamt.
Eventueel een dummy node (noem die bv. root).

Een aantal bewerkingen worden veel lastiger als je geen root hebt (bv. een tak verplaatsen onder een andere node)

Zie dat je zeker een veld depth in je records hebt (jij noemt die lvl, als ik het goed heb).
depth = 0 => (dummy) root
depth = 1 => menu
depth = 2 => submenu

Je werkt met pdo?
Dat is al interessant. Het zal nodig zijn tables te locken en pas te commiten op commando.

Er kunnen best een aantal functies gemaakt worden om de boel wat meer overzichtelijk te maken. Het zijn lange queries.

iets als
insert_as_child($db_object, $parent_id) // inserten onder een node, als eerste subitem (eventueel al de rest opschuiven naar rechts)

insert_as_sibling($db_object, $sibling_id) // inserten als broer/zus rechts van een node

Dat wordt wel een interesante oefening om dit goed te structureren.

Dat openen en sluiten van ul's en li's ... dat is wat zoeken. Nu onmiddelijk even geen tijd, sorry

Tom Swinkels op 07/03/2012 17:39:13:
Toch vind ik die andere manier wel makkelijk, alleen kost het extra rekentijd bij het aanmaken en verwijderen van een item.


Dat is juist.
Maar je moet dat wel zien vanuit de verhouding van het aantal keer dat je de data schrijft/update ten opzichte van hoe veel je data leest.

Je zal ook liever een thumbnail maken op het moment van de upload; dan telkens de GD library aan te spreken bij het bekijken van de foto galerij
Gewijzigd op 08/03/2012 11:36:34 door Kris Peeters
 
Tom Swinkels

Tom Swinkels

08/03/2012 13:43:28
Quote Anchor link
Ik ben er nu achter dat het script wat ik gebruik niet complex genoeg is.
En hij alleen tot een x aantal sub-menu's goed werkt.
Nu heb ik even een schema gemaakt waar ik even vanuit ga: Afbeelding

Als de left en right van de menu items tussen de 1 en 12 hoort het allemaal onder menu 01.
Wanneer de left en right van de menu items tussen de 2 en 9 zitten horen de items onder het sub-menu 01-1A.
Ik weet echter niet hoe ik dit goed kan uitrekenen, hopelijk kan iemand mij hierbij helpen.
 
Mark Kazemier

Mark Kazemier

09/03/2012 14:03:08
Quote Anchor link
Het principe dat hierboven wordt beschreven is het Nested Set model. Een zeer bekend model om hiërarchische structuren op te slaan in een database.

De techniek werkt erg leuk voor als je de volledige boom of een deel daarvan in één keer wil opvragen. Dat kan namelijk eenvoudig met een enkele query die gebruik maakt van de left en de right waarden. Er zijn alleen ook een paar nadelen:
- Het is heel lastig om inserts te doen. Je zal dan heel de boom opnieuw moeten uitrekenen en alle left en right waarden aan moeten passen. Je kan dit wel afvangen door grotere marges te nemen, maar vroeg of laat krijg je hier toch een probleem mee
- Je hebt geen mogelijkheid om de consistentie van je structuur af te dwingen doormiddel van constraints. Hierdoor kunnen er eenvoudig fouten ontstaan doordat je left en right waarden tussen twee menu items overlappen
- Het ophalen van een enkel niveau in je boom is erg lastig

Een andere manier om het op te slaan die in principe ook veel logischer is door een link te maken van een menu_item naar een ander menu_item waar deze onder moet vallen. Je geeft je menu item dus een parent_id. Dit parent_id is null als er geen parent is.

Deze techniek heeft een aantal voordelen:
- Het is eenvoudiger om nieuwe menu_items toe te voegen. Dit kan gewoon door een nieuw record toe te voegen. Je hoeft de andere records niet aan te passen
- Je kan eenvoudig een enkele laag uit je boomstructuur opvragen
- Je kan de consistentie van je boom afdwingen doormiddel van foreign keys

Natuurlijk heeft deze techniek ook nadelen:
- Je hebt recursie nodig om alle records uit een boom op te vragen. Dit kan je in PHP doen door voor elke laag in de boom een query uit te voeren of doormiddel van common table expressions.

Overigens heeft de hele discussie over hoe je dit op gaat slaan in de database zeer weinig te maken met je object model in je applicatie. Dat is namelijk de grap van OOP en met name het Domain model pattern. Je domein model beschrijft de entiteiten en de business rules, maar weet niets af van persistence. Dat is iets dat je vervolgens in een architecture layer neerzet en laat beheren door een ORM of iets dergelijks.
 
Tom Swinkels

Tom Swinkels

11/03/2012 22:46:34
Quote Anchor link
Bedankt voor alle reacties.
Ik ben toch afgestapt van het Nested Set model, er zitten toch teveel nadelen aan.
Nu wil ik een recursive manier gebruiken, ik heb hier een stuk op internet gevonden en dat werkt. Nu wil ik die manier ombouwen tot OO in klasses.

De HTML wil ik niet in de klasse, het moet wel makkelijk zijn om hem bijvoorbeeld om te bouwen naar een template.

Ik zou dit splitsen tot 3 klasses (Menu, MenuItem en MenuMapper). Enkel kan ik de opbouw nog niet helemaal thuis brengen.
Misschien dat jullie mij nog wat tip's kunnen geven?

Mijn opbouw tot nu toe
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
<?php
class Menu
{
    function
getMenu()
    {

    }
}

class MenuItem
{
    private $_data;
    private $_list;
    private $_id;
    private $_parentId;
    
    public function __construct()
    {

        $this->_data = array();
    }

    public function setList($list)
    {

        $this->_list = $list;
    }

    public function setId($id)
    {

        $this->_id = $id;
    }

    public function setParentId($parentId)
    {

        $this->_parentId = $parentId;
    }

    public function getIds()
    {

        return $this->_data['ids'][$this->_id] = $this->_list;
    }

    public function getParents()
    {

        return $this->_data['parents'][$this->_parentId][] = $this->_id;
    }
}

class MenuMapper
{
    public function __construct(PDO $db)
    {

        $this->_db = $db;
    }

    public function getMenu()
    {

        $resultWebn = $this->_db->prepare("SELECT
                                                 webn_id,
                                                 webn_parentid,
                                                 webn_name
                                           FROM
                                                 web_navigation
                                           ORDER BY
                                                 webn_parentid, webn_name
                                          "
);

        $resultWebn->execute(array());
        $listWebn = $resultWebn->fetchAll();

        foreach($listWebn as $list)
        {

            $menuItem = new MenuItem();
            $menuItem->setList($list);
            $menuItem->setId($list['webn_id']);
            $menuItem->setParentId($list['webn_parentid']);
            return $menuItem;
        }
    }
}

?>


Download
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
<?php
$result
= $db->prepare("SELECT
                            webn_id, webn_parentid, webn_name
                        FROM
                            web_navigation
                        ORDER BY
                            webn_parentid, webn_name
                      "
);

$result->execute(array());
$listWebn = $result->fetchAll();

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


foreach($listWebn as $list)
{

    $menuData['items'][$list['webn_id']] = $list;
    $menuData['parents'][$list['webn_parentid']][] = $list['webn_id'];
}

function
buildMenu($parentId, $menuData)
{

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

        $html = '<ul>';
        foreach ($menuData['parents'][$parentId] as $itemId)
        {

            $html .= '<li><a href="">' . $menuData['items'][$itemId]['webn_name'] . '</a>';

            $html .= buildMenu($itemId, $menuData);

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

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

    return $html;
}

?>
Gewijzigd op 11/03/2012 23:08:12 door Tom Swinkels
 



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.