Diskuze: Nefunkční delete modal
V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.

Tvůrce

Zobrazeno 24 zpráv z 24.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.
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>
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ů.
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.
Ahoj Tomáši. Zdrojový kód celé stránky je nahoře (receptury.php), pak je tam i template toho modalu (edit_delete_modal.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.
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_delete.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');
Jak nabádá i nekukej, měl jsem na mysli již vygenerovanou stránku, kterou máš v prohlížeči.
if (isset($_GET['id'])) { - 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?
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?page=receptury#receptura_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 /> <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 /> " 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 /> <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 /> "><span class="glyphicon glyphicon-trash"></span> Ano</a>
</div>
</div>
</div>
</div>
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_delete.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
V tomto podpořím Peter Mlich. Chtělo by to alespoň ověřit zda receptura_delete.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íš.
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).
Jo, mimochodem, ta notice znamena, ze neco nemas definovane
<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>
Na radku 201
V souboru Templates\edit_delete_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['receptura_nazev']
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...
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">
<a class="btn btn-danger" href="App/Assets/receptura_delete.php?id=<br /> <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 /> "><span class="glyphicon glyphicon-trash"></span> Ano</a>
Ostatne, tady mas v html misto cisla jakysi html kod te notice. 214 - receptura_id
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.
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.
Řádek 214 je odkaz na obslužný soubor receptura_delete.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>
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...
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).
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...
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); ?>
Zobrazeno 24 zpráv z 24.