IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.
Avatar
Jaroslav Smrž
Tvůrce
Avatar
Jaroslav Smrž:24.3.2019 12:09

Ahoj kolegové, prosím o pomoc při hledání chyby v následujícím kódu. Vše funguje kromě tlačítka delete. Už to vážně nechápu. V celé aplikaci používám stejný princip pro mazání záznamů z databáze a všude funguje, jen v této sekci z nějakého důvodu ne a už vážně nevím, kde dál hledat chybu. Navíc když tlačítka view i edit fungují i v této sekci. Po kliknutí se má zobrazit bootstrap modal s informací o vybraném záznamu a uživatelském potvrzení odstranění.

receptury.php

<div class="container">
    <div class="alert alert-success" role="alert" style="margin-top: 20px; margin-bottom: 20px;">
        <h1 class="alert-heading">Receptury</h1>
        <hr>
        <p>Umožňuje přidávat, editovat a mazat receptury.</p>
    </div>

    <a href="#addnewreceptura" class="btn btn-primary" data-toggle="modal"><i class="fa fa-plus"></i>&nbsp; Přidat recepturu</a>
    <?php
    if (isset($_SESSION['message'])) {
        ?>
        <div class="alert alert-info text-center" style="margin-top:20px;">
            <?php echo $_SESSION['message']; ?>
        </div>
        <?php
        unset($_SESSION['message']);
    }
    ?>
    <table class="table table-bordered table-striped" style="margin-top:20px;">
        <thead>
        <th>ID</th>
        <th>Název</th>
        <th>Kategorie</th>
        <th>Možnosti</th>
        </thead>
        <tbody>
            <?php
            include_once('App/Assets/connection.php');

            $database = new Connection();
            $db = $database->open();
            try {
                $sql = 'SELECT * FROM receptury ORDER BY receptura_id';
                foreach ($db->query($sql) as $row) {
                    ?>
                    <tr>
                        <td><?php echo $row['receptura_id']; ?></td>
                        <td><?php echo $row['receptura_nazev']; ?></td>
                        <td><?php echo $row['receptura_kategorie']; ?></td>
                        <td>
                            <a href="#receptura_view_<?php echo $row['receptura_id']; ?>" class="btn btn-primary btn-sm" data-toggle="modal"><i class="fa fa-eye"></i>&nbsp;Zobrazit</a>
                            <a href="#receptura_edit_<?php echo $row['receptura_id']; ?>" class="btn btn-success btn-sm" data-toggle="modal"><i class="fa fa-edit"></i>&nbsp;Editovat</a>
                            <a href="#receptura_delete_<?php echo $row['receptura_id']; ?>" class="btn btn-danger btn-sm" data-toggle="modal"><i class="fa fa-trash"></i>&nbsp;Odstranit</a>
                        </td>
                        <?php include('App/Templates/edit_delete_modal.php'); ?>
                    </tr>
                    <?php
                }
            } catch (PDOException $e) {
                echo "Oooops! Našel se problém s připojením k databázi: " . $e->getMessage();
            }

            $database->close();
            ?>
        </tbody>
    </table>
</div>

edit_delete_mo­dal.php

<!-- Delete RECEPTURA-->
<div class="modal fade" id="receptura_delete_<?php echo $row['receptura_id']; ?>" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <center><h4 class="modal-title" id="myModalLabel">Odstranit recepturu</h4></center>
                <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
            </div>
            <div class="modal-body">
                <p class="text-center">Určitě chcete recepturu odstranit?</p>
                <h2 class="text-center"><?php echo $row['receptura_nazev']; ?></h2>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal"><span class="glyphicon glyphicon-remove"></span> Zrušit</button>
                <a href="App/Assets/receptura_delete.php?id=<?php echo $row['receptura_id']; ?>" class="btn btn-danger"><span class="glyphicon glyphicon-trash"></span> Ano</a>
            </div>
        </div>
    </div>
</div>

Zkusil jsem: Přepsat znovu celou stránku receptury.php, celý template modal v edit_delete_mo­dal.php i obslužný kód receptura_dele­te.php a pořád stejný problém.

Chci docílit: Funkčního tlačítka odstranit, které otevře bootstrap modal s informací o položce a ověření, zda chce uživatel záznam skutečně odstranit. Budu vděčný za každou pomoc. Nemohu ten problém najít.

Odpovědět
24.3.2019 12:09
/* Life runs on code */
Avatar
nekukej
Člen
Avatar
Odpovídá na Jaroslav Smrž
nekukej:24.3.2019 13:02

Podívej se, jestli je ten modal v html (v prohlížeči)?
Například zde je ukázka, kde se používá místo

<a></a>

button, který má nastavený parametr data-target

<!-- Trigger the modal with a button -->
<button type="button" class="btn btn-info btn-lg" data-toggle="modal" data-target="#myModal">Open Modal</button>
 
Nahoru Odpovědět
24.3.2019 13:02
Avatar
Jaroslav Smrž
Tvůrce
Avatar
Odpovídá na nekukej
Jaroslav Smrž:24.3.2019 14:39

Tak jsem zkoušel i button, ale pořád stejný příběh. Musí být problém někde v předávání id. Když pojmenuji prvky staticky - např myModal, tak funguje i s <a> </a>, ale jakmile vložím PHP pro předání požadovaného řádku z databáze, tak se modal neotevře. Už vážně nevím, kde je problém. Na jiných místech aplikace stejný kód běží bez problémů.

Nahoru Odpovědět
24.3.2019 14:39
/* Life runs on code */
Avatar
Odpovídá na Jaroslav Smrž
Tomáš Novotný:24.3.2019 17:57

Ahoj, bylo by možné spíše přiložit zdrojový kód stránky? Tu na první pohled nic zásadního nevidím.

Nahoru Odpovědět
24.3.2019 17:57
∞ ... the exact amount of possibilities how to deal with the situation ... so by calm, your solution is one of many
Avatar
Jaroslav Smrž
Tvůrce
Avatar
Odpovídá na Tomáš Novotný
Jaroslav Smrž:24.3.2019 20:31

Ahoj Tomáši. Zdrojový kód celé stránky je nahoře (receptury.php), pak je tam i template toho modalu (edit_delete_mo­dal.php), z toho jsem sem vložil pouze inkriminovaný ID pro delete receptur. Jinde by chyba být neměla neboť výpis z databáze na této stránce funguje, i jednotlivá tlačítka (view a edit) také fungují, jen tomu deletu se nechce, což vůbec nechápu, protože stejný kód používám pro suroviny, kategorie i správu uživatelů a vše OK.

Nahoru Odpovědět
24.3.2019 20:31
/* Life runs on code */
Avatar
Jaroslav Smrž
Tvůrce
Avatar
Jaroslav Smrž:24.3.2019 20:42

Přidám ještě obslužný soubor pro faktický výmaz záznamu z DB, ale to nic neřeší, pokud se modal nezobrazí a neklikne se na "Ano, odstranit".

receptura_dele­te.php

<?php

include_once('connection.php');

if (isset($_GET['id'])) {
    $database = new Connection();
    $db = $database->open();
    try {
        $sql = "DELETE FROM receptury WHERE receptura_id = '" . $_GET['id'] . "'";
        $_SESSION['message'] = ( $db->exec($sql) ) ? 'Záznam úspěšně vymazán' : 'Něco je špatně, záznam nelze vymazat';
    } catch (PDOException $e) {
        $_SESSION['message'] = $e->getMessage();
    }

    $database->close();
} else {
    $_SESSION['message'] = 'Nejprve vyberte záznam';
}

header('location: ../../index.php?page=receptury');
Nahoru Odpovědět
24.3.2019 20:42
/* Life runs on code */
Avatar
nekukej
Člen
Avatar
nekukej:24.3.2019 22:13

Podívej se do zdrojáku html v prohlížeči (vetšinou F12) jestli ti tam sedí ty id. Jelikož se ti neotevře ten modal typl bych to spíše chybu v html. Možná se do id vloží nějaký bordel nebo tak.

 
Nahoru Odpovědět
24.3.2019 22:13
Avatar
Odpovídá na Jaroslav Smrž
Tomáš Novotný:25.3.2019 7:25

Jak nabádá i nekukej, měl jsem na mysli již vygenerovanou stránku, kterou máš v prohlížeči.

Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
Nahoru Odpovědět
25.3.2019 7:25
∞ ... the exact amount of possibilities how to deal with the situation ... so by calm, your solution is one of many
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:25.3.2019 8:11

if (isset($_GET['i­d'])) { - s takovou konstrukci opatrne. Nemas tam podminku na delete. Mozna, ze to mas samostatny soubor, ale i tak je bezpecnejsi pridat skryty input nebo overovat value z buttonu nebo jinak si pojistit, ze uzivatel skutecne chce pouzit delete. A take by bylo moc fajn tam pridat overovani prav. aspon, ze je prihlaseny :)

$sql = "DELETE FROM receptury WHERE receptura_id = '" . $_GET['id'] . "'";
S timto take dost opatrne. Nemas tam zadnou ochranu proti hackerum. Bys mel pouzit pdo-prepare nebo sprintf nebo vsprintf.
Ja byt hacker, tak si zavolam primo stranku

receptura_delete.php?id=' OR '1'='1
        $sql = "DELETE FROM receptury WHERE receptura_id = '" . $_GET['id'] . "'";
        $sql = "DELETE FROM receptury WHERE receptura_id = '"."' OR '1'='1" . "'";
        $sql = "DELETE FROM receptury WHERE receptura_id = '' OR '1'='1'"; // coz je totez jako
        $sql = "DELETE FROM receptury";
To bys asi nerad, ze?

Ok, ok. Jak hledat tu chybu s dialogem?

  1. Jak rikaji kluci, v prvni rade musis mit spravne html kod. Ten se da zjistit ulozenim do souboru (treba pomoci ob_, ob_get_content, file_put_content). Nebo, pouzit www prohlizec, pravym tlacitkem a kdyz nemas nic oznacene mysi, melo by tam byt zobrazit-zdrojovy-kod. Nebo to najdes nekde v menickach. Nebo se da googlem najit navod pro konkretni prohlizec, kde to tlacitko hledat. A nebo soubor - Ulozit stranku...
  2. Pokud mas html ok, pak muzes zkoumat js kod. Opet, treba Firefox, Nastroje - vyvoj webu - konzola. F5 (refresh stranky). Nemela by naskocit zadna chyba. A muzes kliknout na tlacitko, opet by nemela vyskocit zadna chyba. Pokud ano, pise ti obvykle cislo radku v html kodu, ktery ma prohlizec (zobrazit- zdrojovy-kod)
  3. A jeste muzes mit chybu nekde v php, v nejake uvozovce. To je pak dobre si treba mezi par radku dat echo 1; echo 2;... A na konci pridat die(); zastavit tak php kod. Uvidis, kolik z tech echo se provede. Pokud vsechny, tak si vyberes zas jina mista a die() presunes na konec.
 
Nahoru Odpovědět
25.3.2019 8:11
Avatar
Jaroslav Smrž
Tvůrce
Avatar
Odpovídá na nekukej
Jaroslav Smrž:25.3.2019 8:46

Díky moc, to mě nenapadlo. Samozřejmě je tam problém. Všechny id sedí jak u view, tak u edit, ale u delete vyhazuje undefined index : receptura_id. Koukal jsem i na směrovaní a to je v pořádku. Podle row odkazuje na příslušný id (index.php?pa­ge=receptury#re­ceptura_delete1)

<div tabindex="-1" class="modal fade" id="receptura_view_1" role="dialog" aria-hidden="true" aria-labelledby="myModalLabel">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <center><h4 class="modal-title" id="myModalLabel">Podrobnosti</h4></center>
                <button class="close" aria-hidden="true" type="button" data-dismiss="modal">×</button>
            </div>
            <div class="modal-body">
                <h2 class="text-center">Svíčková na smetaně</h2>
            </div>
            <div class="modal-footer">
                <button class="btn btn-default" type="button" data-dismiss="modal"><span class="glyphicon glyphicon-remove"></span> Zavřít</button>
            </div>
        </div>
    </div>
</div>
<div tabindex="-1" class="modal fade" id="receptura_delete_<br />&#10;<b>Notice</b>:  Undefined index: receptura_id in <b>C:\xampp\htdocs\Receptury\App\Templates\edit_delete_modal.php</b> on line <b>201</b><br />&#10;" role="dialog" aria-hidden="true" aria-labelledby="myModalLabel">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <center><h4 class="modal-title" id="myModalLabel">Odstranit recepturu</h4></center>
                <button class="close" aria-hidden="true" type="button" data-dismiss="modal">×</button>
            </div>
            <div class="modal-body">
                <p class="text-center">Určitě chcete recepturu odstranit?</p>
                <h2 class="text-center"><br>
<b>Notice</b>:  Undefined index: receptura_nazev in <b>C:\xampp\htdocs\Receptury\App\Templates\edit_delete_modal.php</b> on line <b>210</b><br>
</h2>
            </div>
            <div class="modal-footer">
                <button class="btn btn-default" type="button" data-dismiss="modal"><span class="glyphicon glyphicon-remove"></span> Zrušit</button>
                <a class="btn btn-danger" href="App/Assets/receptura_delete.php?id=<br />&#10;<b>Notice</b>:  Undefined index: receptura_id in <b>C:\xampp\htdocs\Receptury\App\Templates\edit_delete_modal.php</b> on line <b>214</b><br />&#10;"><span class="glyphicon glyphicon-trash"></span> Ano</a>
            </div>
        </div>
    </div>
</div>
Nahoru Odpovědět
25.3.2019 8:46
/* Life runs on code */
Avatar
Jaroslav Smrž
Tvůrce
Avatar
Odpovídá na Peter Mlich
Jaroslav Smrž:25.3.2019 9:01

Děkuji za upozornění, ale ověření uživatele se řeší na index.php a všechny tyto stránky se dynamicky vkládají do něj. Soubor receptura_dele­te.php je pouze obslužný soubor pro tlačítko Ano, odstranit v modalu. Ošetření je přímo ve třídě connection. Navíc celá aplikace poběží pravděpodobně pouze na lokálním serveru, uživatelé budou jen asi 3 a není pochyb, že 2 manažeři a 1 majitel restaurace nejsou machři na SQL :)

Nahoru Odpovědět
25.3.2019 9:01
/* Life runs on code */
Avatar
Odpovídá na Jaroslav Smrž
Tomáš Novotný:25.3.2019 9:31

V tomto podpořím Peter Mlich. Chtělo by to alespoň ověřit zda receptura_dele­te.php spouští někdo oprávněný (min. přihlášený uživatel). Třeba přes require nějakého login.php, využití session, atp... Ošetřování vstupu od uživatele dle mne není otázka výběru. Je to nutnost, protože nikdy nevíš.

Nahoru Odpovědět
25.3.2019 9:31
∞ ... the exact amount of possibilities how to deal with the situation ... so by calm, your solution is one of many
Avatar
Peter Mlich
Člen
Avatar
Odpovídá na Jaroslav Smrž
Peter Mlich:25.3.2019 10:33

To je na zvazeni. Ja bych to tam urcite dal. Oni mozna nebudou hackovat schvalne, ale muze nastat nejaky nepredvidatelny stav. Napriklad budes kopirovat cast kodu a zapomenes tam neco upravit, tak ti to bude treba smerovat prave na tuto stranku a posilat id. Treba pro uplne jinou tabulku.
Zkratka je dobre si overit, odkud dotaz prisel a zda je opravneny. Zvlast, pokud se to tyka prave DELETE nebo UPDATE (nez neco smazat nebo prepsat omylem).

 
Nahoru Odpovědět
25.3.2019 10:33
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:25.3.2019 10:38

Jo, mimochodem, ta notice znamena, ze neco nemas definovane

<b>Notice</b>: Undefined index: receptura_nazev in <b>C:\xampp\htdoc­s\Receptury\Ap­p\Templates\e­dit_delete_mo­dal.php</b> on line <b>210</b><br>
</h2>

Na radku 201
V souboru Templates\edit_de­lete_modal.php
se pokousis asi pres echo vypsat nejake pole. V tom poli ale nemas definovany index 'receptura_nazev', cili tam je neco jako
echo $row['receptu­ra_nazev']

 
Nahoru Odpovědět
25.3.2019 10:38
Avatar
Jaroslav Smrž
Tvůrce
Avatar
Odpovídá na Tomáš Novotný
Jaroslav Smrž:25.3.2019 10:45

Jasně, máš pravdu. Koukám, že mi tam vypadl řádek se session_start(). Normálně ho v kódu mám, nevím, proč se mi nezkopíroval sem...

Nahoru Odpovědět
25.3.2019 10:45
/* Life runs on code */
Avatar
Jaroslav Smrž
Tvůrce
Avatar
Odpovídá na Peter Mlich
Jaroslav Smrž:25.3.2019 10:46

Ano, přesně tak. Vypisuje se tam

<div class="modal fade" id="receptura_delete_<?php echo $row['receptura_id']; ?>" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
Nahoru Odpovědět
25.3.2019 10:46
/* Life runs on code */
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:25.3.2019 10:54
<a class="btn btn-danger" href="App/Assets/receptura_delete.php?id=<br />&#10;<b>Notice</b>:  Undefined index: receptura_id in <b>C:\xampp\htdocs\Receptury\App\Templates\edit_delete_modal.php</b> on line <b>214</b><br />&#10;"><span class="glyphicon glyphicon-trash"></span> Ano</a>

Ostatne, tady mas v html misto cisla jakysi html kod te notice. 214 - receptura_id

 
Nahoru Odpovědět
25.3.2019 10:54
Avatar
Odpovídá na Jaroslav Smrž
Tomáš Novotný:25.3.2019 10:56

Teď nějak nerozumím Jardo. Start session by snad měla být jednou v nějakém login.php po validním přihlášení. Tu by měla spíše být kontrola zda session exist, případně zda obsahuje určité parametry např. role přihlášeného uživatele.

Nahoru Odpovědět
25.3.2019 10:56
∞ ... the exact amount of possibilities how to deal with the situation ... so by calm, your solution is one of many
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:25.3.2019 11:18

Teoreticky by ti ten kod nahore mel fungovat, to php. Uz driv jsem na to koukal, ze je to ok. Ale pokud ti to vygeneruje to html s temi notice, tak mas neco spatne.

  • cyklus jsi mozna ukoncil drive nez vypisujes tu sablonu
  • prejmenoval jsi sloupce v db
  • muzes zkusit do toho includovaneho pridat na zacatek: <?php global $row; ?>
Editováno 25.3.2019 11:18
 
Nahoru Odpovědět
25.3.2019 11:18
Avatar
Jaroslav Smrž
Tvůrce
Avatar
Odpovídá na Peter Mlich
Jaroslav Smrž:25.3.2019 11:21

Řádek 214 je odkaz na obslužný soubor receptura_dele­te.php a je v patičce modalu.

<div class="modal-footer">
       <button type="button" class="btn btn-default" data-dismiss="modal"><span class="glyphicon glyphicon-remove"></span> Zrušit</button>
       <a href="App/Assets/receptura_delete.php?id=<?php echo $row['receptura_id']; ?>" class="btn btn-danger"><span class="glyphicon glyphicon-trash"></span> Ano</a>
</div>
Nahoru Odpovědět
25.3.2019 11:21
/* Life runs on code */
Avatar
Jaroslav Smrž
Tvůrce
Avatar
Odpovídá na Peter Mlich
Jaroslav Smrž:25.3.2019 11:27

Díky moc, sloupce v DB jsem kontroloval a OK, zkusím ještě kouknout na cyklus, jak říkáš, případně vyzkouším global. Je mi právě záhadou, proč to jinde funguje a jen tohle jediné tlačítko v této sekci ne. Teď alespoň už vím, že se tam odněkud generuje html bordel. Zbývá zjistit kde...

Nahoru Odpovědět
25.3.2019 11:27
/* Life runs on code */
Avatar
Tomáš Novotný:25.3.2019 11:52

Ještě bych zkusil mrknout do výsledku dotazu z DB třeba kombinací echo '<pre>'; print_r($row); ... třeba pro každou kategorii v rámci cyklu. Global $row bych moc nedoporučoval, pak bys patrně někde měl používat unset($row).

Nahoru Odpovědět
25.3.2019 11:52
∞ ... the exact amount of possibilities how to deal with the situation ... so by calm, your solution is one of many
Avatar
Jaroslav Smrž
Tvůrce
Avatar
Odpovídá na Tomáš Novotný
Jaroslav Smrž:25.3.2019 11:57

Promiň, já špatně pochopil. U deletu ošetření nemám. Pouze u přidání

$stmt = $db->prepare("INSERT INTO receptury (receptura_nazev, receptura_kategorie) VALUES (:receptura_nazev, :receptura_kategorie)");

Delete a edit ošetřím, až se mi to podaří dát do provozu... :-?

Nahoru Odpovědět
25.3.2019 11:57
/* Life runs on code */
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:25.3.2019 13:49

Mozna bude lepsi pouzit var_dump. Vypise i typ objektu. printr je dobre, ale kdyz je row null, tak vrati prazdny string a z toho nic nezjistis. A dal bych to mozna primo do te sablony na zacatek.

<?php echo '<pre>'; var_dump($row); ?>
 
Nahoru Odpovědět
25.3.2019 13:49
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 24 zpráv z 24.