Database op nummer sorteren. (ex. 1, 2, 3, ...)

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Dutch Caffeine

Dutch Caffeine

04/01/2009 20:57:00
Quote Anchor link
Geachte allemaal,

Ten eerste wil ik jullie allemaal de beste wensen voor 2009 wensen!

Ik heb een heel leuk menu systeempje ontwikkeld, wat perfect werkt. Maar echter heb ik 1 groot probleem, het probleem zit in de opbouw van het menu (op welke positie hoort de menu item te staan).

Het veranderen van de positie werkt geweldig. Maar nu het verwijderen van een menu item, daar zit de grote fout. Eerst even wat uitleg hoe ik het menu systeem in elkaar heb gezet.

De database:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
CREATE TABLE IF NOT EXISTS `phpbb_menu` (
  `menu_id` int(9) NOT NULL AUTO_INCREMENT,
  `menu_name` varchar(255) NOT NULL,
  `menu_link` varchar(255) NOT NULL,
  `menu_disabled` tinyint(1) NOT NULL,
  `menu_not_created` tinyint(1) NOT NULL,
  `menu_order` int(5) NOT NULL,
  PRIMARY KEY (`menu_id`),
  UNIQUE KEY `menu_place_2` (`menu_place`),
  KEY `menu_place` (`menu_place`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=11 ;


Echter is voor het probleem zelf menu_order nodig. De menu_order tabel ziet er zo uit als hij gevuld is:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
+---------------+---------------+
| menu_name    | menu_order    |
+--------------------------------
| Home        | 1        |
| Forum        | 2        |
| Rules        | 3        |
| Portfolio    | 4        |
| Nieuws    | 5        |
| FAQ        | 6        |
+---------------+---------------+


Nu wil ik bijv. de menu item Rules verwijderen die de menu_order 4 met zich mee draagt. Nou is dat verwijderen niet een groot probleem. Maar zo gouw ik de boel weer laad in een array en die array weer laad in de template systeem, dan krijg ik een error in firefox. Die error is echter niet van belang hier, hij zegt gewoon weg dat de html indeling verkeerd is en niet geladen kan worden. Maar om dat probleem te voorkomen moet ik de hele menu_order aanpassen. En daar zit het grote probleem.

Als ik de menu item Rules heb verwijderd ziet mijn tabel er zo uit:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
+---------------+---------------+
| menu_name    | menu_order    |
+--------------------------------
| Home        | 1        |
| Forum        | 2        |
| Portfolio    | 4        |
| Nieuws    | 5        |
| FAQ        | 6        |
+---------------+---------------+


Je ziet daar in dat hij geen order nummer 3 heeft.

Wat ik uiteindelijk wil is dat de tabel er zo uitkomt te zien:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
+---------------+---------------+
| menu_name    | menu_order    |
+--------------------------------
| Home        | 1        |
| Forum        | 2        |
| Portfolio    | 3        |
| Nieuws    | 4        |
| FAQ        | 5        |
+---------------+---------------+


En om dat te krijgen moet je dat tijdens het verwijderen ook veranderen, maar dan komt de grote vraag hoe. De volgende code heb ik. Ik weet dat ergens iets goed fout doe!

Denk er aan, dit is een code uit een class. En de class is geschreven voor php4
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
<?php
function delete_item($menu_id)
{

    global $db;
    
    $place = $this->get_order_from_item($menu_id);
    
    // First delete and reload
    $sql = "DELETE FROM " . MENU_TABLE . " WHERE menu_id = " . $menu_id;
    $db->sql_query($sql);
    
    $this->reload_items();
    
    // Push everything up!
    if($place != $this->get_highest_position())
    {

        $total = count($this->menus);
        
        $t = $place;
        
        $i = 1;
        while($i <= $total-$place-1)
        {

            $sql = "UPDATE " . MENU_TABLE . "
                    SET menu_place = "
. $t . "
                    WHERE menu_place > "
. $place;
            
            $db->sql_query($sql);
            
            $t--;
            $i++;
        }

            
        $this->reload_items();
    }
}

?>


Zou iemand me hiermee kunnen helpen?

Mijn dank zal groot zijn.

Alexander de Jong

?>
Gewijzigd op 01/01/1970 01:00:00 door Dutch Caffeine
 
PHP hulp

PHP hulp

23/12/2024 20:58:34
 
Joren de Wit

Joren de Wit

04/01/2009 21:45:00
Quote Anchor link
In principe zou het niet uit moeten maken als er een record mist, aan de volgorde waarop de records geselecteerd worden verandert immers niets als je gewoon op menu_order blijft sorteren.

Wel een probleem wordt het als je de waarde van menu_order niet alleen gebruikt om te sorteren, maar ook voor andere doeleinden in je script. Maar goed, dan ben je ook niet op de juiste manier bezig. Wil je graag een nummertje bij de verschillende records? Houd dan gewoon een tellertje bij wanneer je de resultaat set fetcht.

Als ik helemaal verkeerd zit moet je het zeggen, maar het lijkt me dat dit het probleem is...
 
Hipska BE

Hipska BE

04/01/2009 21:47:00
Quote Anchor link
$menu_id is welke je wil verwijderen.

om alles te doen kan dit in 3 query's

1) SELECT menu_order FROM ... WHERE menu_id = $menu_id
2) DELETE FROM ... WHERE menu_id = $menu_id
3) UPDATE ... SET menu_order = menu_order-1 WHERE menu_order > $menu_order

en telkens tussendoor foutafhandeling doen van de query
 
Dutch Caffeine

Dutch Caffeine

04/01/2009 21:50:00
Quote Anchor link
Nou je het zegt ik denk denk dat ik het ook verkeerd doe. Ik zal is even kijken hoe ik dit open een andere manier kan doen. Misschien met right_id en left_id.

Bedankt voor je reachtie blanche.

Btw. de array $menus wordt zo ingedeeld:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
<?php
$this
->menus[$row['menu_place']] = array(
                'name'            => (!empty($user->lang[$row['menu_name']])) ? $user->lang[$row['menu_name']] : $row['menu_name'],
                'name_var'        => $row['menu_name'],
                'link'            => append_sid($phpbb_root_path . $row['menu_link']),
                'link_db'        => $row['menu_link'],
                'id'            => $row['menu_id'],
                'order'            => $row['menu_place'],
                'not_created'    => ($row['menu_not_created'] == 1) ? true : false,
                'disabled'        => ($row['menu_disabled'] == 1) ? true : false,
            );

?>


Die array wordt zo geladen in de template parser:
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
<?php
function generate_menu()
{

    global $menu, $template;
    
    $menu->load_items();
    
    $menu_size = count($menu->menus);
    
    $basename = basename($_SERVER['SCRIPT_NAME']);
    
    $i = 1;
    
    while($i <= $menu_size)
    {

        $template->assign_block_vars('menu', array(
            'ID'            => $menu->menus[$i]['id'],
            'NAME'            => $menu->menus[$i]['name'],
            'LINK'            => $menu->menus[$i]['link'],
            'NOT_CREATED'    => $menu->menus[$i]['not_created'],
            'DISABLED'        => $menu->menus[$i]['disabled'],
            'ACTIVE'        => ($basename == $menu->menus[$i]['link_db']) ? true : false,
            'ORDER'            => $menu->menus[$i]['order'],
        ));

        $i++;
    }
}

?>
 
Frank -

Frank -

04/01/2009 21:50:00
Quote Anchor link
Ik ben heel benieuwd hoe jij dan sorteert, met een "gewone" ORDER BY maakt het echt niet uit of je nu 1,2,3,4,5 of 1,8,19,100,273 op een rij zet. Het kan niet anders of er zit een foutje in je SELECT-query of je gebruikt geen correcte code om het resultaat weer te geven.

Jouw probleem kun je niet/nauwelijks oplossen met UPDATE en/of DELETE-queries, die zullen hooguit wat symptomen kunnen bestrijden. En dan nog kan het fout gaan.

Zorg voor een goede SELECT en correcte ORDER BY en jouw probleem verdwijnt als sneeuw voor de zon. Uiteraard moet je wel correcte html aanmaken, maar dat heeft niets met je database te maken, laat staan met een sortering.
 
Dutch Caffeine

Dutch Caffeine

22/01/2009 18:13:00
Quote Anchor link
O ja, ik heb de oplossing!!!

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
<?php
class menu {
function
remove_item($menu_id)
    {

        global $db;
        
        $place = $this->get_order_from_item($menu_id);
        $hplace = $this->get_highest_position();
        
        if($place == $hplace)
        {

            $sql = "DELETE FROM " . MENU_TABLE;
            $sql .= " WHERE menu_id = " . $menu_id;
            $db->sql_query($sql);
            return;
        }

        
        $sql = "DELETE FROM " . MENU_TABLE;
        $sql .= " WHERE menu_id = " . $menu_id;
        $db->sql_query($sql);
        
        for($i = $place+1; $i <= $hplace; $i++)
        {

            $_menu_id = $this->get_item_from_order($i);
            $order = $i-1;
            $sql = "UPDATE " . MENU_TABLE . " SET menu_order = " . $order . " WHERE menu_id = " . $_menu_id;    
            $db->sql_query($sql);    
        }

        
        $this->reload_items();
    }
    
    function
push_item_up($menu_id)
    {

        global $db;
        
        $place = $this->get_order_from_item($menu_id);
        $update_place = $place-1;
        
        // get the place above the current menu item.
        $above_item = $this->get_item_from_order($update_place);
        
        // update the current menu
        $sql = "UPDATE " . MENU_TABLE;
        $sql .= " SET menu_order = 0";
        $sql .= " WHERE menu_id = " . $menu_id;
        $db->sql_query($sql);
        
        $sql = "UPDATE " . MENU_TABLE;
        $sql .= " SET menu_order = " . $place;
        $sql .= " WHERE menu_id = " . $above_item;
        $db->sql_query($sql);
        
        $sql = "UPDATE " . MENU_TABLE;
        $sql .= " SET menu_order = " . $update_place;
        $sql .= " WHERE menu_id = " . $menu_id;
        $db->sql_query($sql);
        
        $this->reload_items();
    }
    
    function
push_item_down($menu_id)
    {

        global $db;
        
        // get the current place
        $place = $this->get_order_from_item($menu_id);
        $update_place = $place+1;
        
        // get the place above the current menu item.
        $above_item = $this->get_item_from_order($update_place);
        
        // update the current menu
        $sql = "UPDATE " . MENU_TABLE;
        $sql .= " SET menu_order = 0";
        $sql .= " WHERE menu_id = " . $menu_id;
        $db->sql_query($sql);
        
        $sql = "UPDATE " . MENU_TABLE;
        $sql .= " SET menu_order = " . $place;
        $sql .= " WHERE menu_id = " . $above_item;
        $db->sql_query($sql);
        
        $sql = "UPDATE " . MENU_TABLE;
        $sql .= " SET menu_order = " . $update_place;
        $sql .= " WHERE menu_id = " . $menu_id;
        $db->sql_query($sql);
        
        $this->reload_items();
    }
}

?>
 
Frank -

Frank -

22/01/2009 18:54:00
Quote Anchor link
Tja, leuk, maar je probeert hiermee een niet-bestaand probleem op te lossen. Je kunt gaan updaten tot je een ons weegt, de sortering wordt er echt niet anders van. Ga dan niet updaten, dat is een sneller en er kan minder fout gaan. Het had je ook minder tijd gekost om te bouwen, je hoeft er namelijk helemaal niets voor te doen... Al het werk is wat dat betreft ook voor niets geweest.

Had tenminste transactions gebruikt, dan had je er nog iets aan gehad.
 



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.