Avatar
Michal Kuba
Redaktor
Avatar
Michal Kuba:

Ahoj.
Už jednou jsem se snažil rozlousknout problém, jak vytvořit jednoduchý filtr na webu.

Po měsíci mimo civilizaci jsem se vrátil k PC a lehce s problematikou pohnul, jenže stále filtr nefunguje.

Kontroler:

public function zpracuj($parametry){

        $spravceInzeratu = new SpravceInzeratu();
                $spravceUzivatelu = new SpravceUzivatelu();
                $uzivatel = $spravceUzivatelu->vratUzivatele();

                $this->data['admin'] = $uzivatel && $uzivatel['admin'];

                $inzeraty=$spravceInzeratu->vratNejnovejsi();


             $this->data['jmeno']='Nejnovější inzeráty';

        if (!empty($inzeraty))
        {
         $this->data['inzeraty'] = $inzeraty;
         $this->data['nazev']=$kategorie;
        }
else $this->pridejZpravu2('Nebyl vložen žádný inzerát!');
                $this->hlavicka = array(
                        'titulek' => 'Mainos - snadná inzerce',
                        'klicova_slova' => 'mainos, inzerce zdarma, inzeráty, mainos.cz',
                        'popis' => 'Inzeráty na Mainos.cz'
                );


                if (!empty($parametry[1]) && $parametry[1] == 'odstranit')
                {
                        $this->overUzivatele(true);
                        $spravceInzeratu->odstranInzerat($parametry[0]);
                        $this->presmeruj('');
        }

                        $this->pohled = 'testing';

           if($_POST){
                $inzeraty=$spravceInzeratu->vratInzerat();
               $_SESSION['filtr']= $filtr = array(
                                        'castTextu' => $_POST["castTextu"],
                        'castKategorie' => $_POST["castKategorie"],
                        'castMesto' => $_POST["castMesto"]);

               if(!empty($_SESSION['filtr']['castTextu'])){
              $this->data['inzeraty'] = $inzeraty;
               }
           }

Šablona:

<article><header><h1><?= $jmeno?></h1></header>
     <button  onclick="zobrazSkryj('oddil1')">Filtr</button>
<div id="oddil1" class="skryvany"><div class="filtr">
        <form method="POST" name="filtr" id="filtrovani"><table class="tabFiltr"><tr>
                    <td><input type="text"  name="castTextu" placeholder="Hledané slovo"></td>
                     <td> <input type="text"  name="castKategorie" placeholder="Kategorie"></td>
           <td> <input type="text"  name="castMesto" placeholder="Město"/>


           </td></tr><tr><td></td><td ><button id="tabUprostred">Filtrovat!</button></td><td></td></tr></table> </form>

    </div></div></div>


        <?php foreach ($inzeraty as $inzerat): ?><section><table class="radekInzerat"><tr><td class="inzerat">
                        <div class="vRade"><a class="titulek"><?= $inzerat['titulek'] ?></a><a class="uppercase">(<?= $inzerat['kategorie'] ;?>)</a></div>
                <p class="textInzeratu"><?= $inzerat['text'] ?></p>

                    </td>
                    <td class="td2"><a class="mesto"><?= $inzerat['mesto'] ?></a><br>

                            <a class="reagovat" href="reagovat?autor=<?=$inzerat['autor']?>">Reagovat</a>
                    </td></tr></table></section><?php endforeach; ?>

a zde jen pro jistotu model:

public function vratInzerat($parametry)
        {
                $ress= Db::dotazVsechny('
                        SELECT *
                        FROM inzeraty
                        WHERE upresneni=?
                        ORDER BY datum_vlozeni DESC
    ',array($parametry));
                return $ress;
        }

Možná v tom je nějaká drobná chyba - překlep, nebo taky ne..

Zatím to je tak, že když zadám slovo, které jistě v inzerátu i názvu je a filtruji, načte se prázdná stránka - vše tam je, jen žádné vypsané inzeráty..

Předem díky za nějakou radu :)

 
Odpovědět 3.8.2015 16:41
Avatar
Martin Konečný (pavelco1998):

zdar,
nějak nevidim, že bys metodě SpravceInzera­tu::vratInzerat() předával nějaké parametry. Je to tak úmyslně?

 
Nahoru Odpovědět 3.8.2015 17:06
Avatar
Michal Kuba
Redaktor
Avatar
Odpovídá na Martin Konečný (pavelco1998)
Michal Kuba:

Já si nějak myslel, že to bude částečně tím, jenže ani takto to nefunguje:

if($_POST){

              $_SESSION['filtr']= $filtr = array(
                                       'castTextu' => $_POST["castTextu"],
                       'castKategorie' => $_POST["castKategorie"],
                       'castMesto' => $_POST["castMesto"]);
              $inzeraty=$spravceInzeratu->vratInzerat($_SESSION['filtr']);

              if(!empty($_SESSION['filtr']['castTextu'])){
             $this->data['inzeraty'] = $inzeraty;
              }
          }

Zatím předávám jen tu jednu část SESSION, ale víc jich udělaných zatím nemám tak proto bez upřesnění.. tohle je asi špatná cesta že?

 
Nahoru Odpovědět 3.8.2015 17:15
Avatar
Michal Kuba
Redaktor
Avatar
Odpovídá na Martin Konečný (pavelco1998)
Michal Kuba:

Už to mám. Měl jsem špatně model, hledal jsem ve špatném sloupci.. jenže poslední zádrhel, a to je spíš moje neznalost všech příkazů, jak udělat, aby se z databáze poslaly všechny výsledky obsahující to slovo. Teď musím napsat doslova celý text inzerátu aby se vyfiltroval.. mám

WHERE text=?

a to právě porovnává jen celé obsahy toho sloupečku a ne jen jedno slovo..

 
Nahoru Odpovědět 3.8.2015 18:00
Avatar
Michal Kuba
Redaktor
Avatar
Michal Kuba:

Ani zástupné znaky mi nejdou nějak použít.

WHERE text=%?%      nebo   text=%"?"%
 
Nahoru Odpovědět 3.8.2015 18:04
Avatar
Martin Konečný (pavelco1998):

Pak ti asi pomůže operátor LIKE. Ten dokáže vyhledat záznam, který obsahuje část slova, např.

SELECT data FROM table
WHERE column LIKE "%abc%"

ta procenta znamenají, že může být jakýkoliv text před a po.

 
Nahoru Odpovědět 3.8.2015 18:05
Avatar
Michal Kuba
Redaktor
Avatar
Odpovídá na Martin Konečný (pavelco1998)
Michal Kuba:

Jojo, ted jsem to našel, jenže v tom dotazu mám otazník a to je hodnota poslaná od uživatele.. pořád mi to s tím otazníkem blbne.. A když to udělám takhle

text LIKE "%?%"

tak to vrací prázdno, protože tam mám ten otazník blbej..

ani když jen procenta obalím uvozovkama tak nic..

Editováno 3.8.2015 18:11
 
Nahoru Odpovědět 3.8.2015 18:08
Avatar
Martin Konečný (pavelco1998):

Musíš tam nechat jen ten otazník a hodnotu včetně procent hodit až do nějaké execute metody.

 
Nahoru Odpovědět 3.8.2015 18:56
Avatar
Michal Kuba
Redaktor
Avatar
Odpovídá na Martin Konečný (pavelco1998)
Michal Kuba:

Úplně nevím co myslíš tou execute metodou.. Nepřiblížíš mi to prosím? :)

 
Nahoru Odpovědět 3.8.2015 19:00
Avatar
Martin Konečný (pavelco1998):

Jo, ty ty parametry předáváš rovnou metodám jako Db::dotazVsechny() apod. Mám tím na mysli ten druhej parametr :)

Db::dotazVsechny("
        SELECT data
        FROM clanek
        WHERE nadpis LIKE ?
", array("%{$nadpis}%"));

jen si nejsem jistý, zda takhle funguje správně automatické ošetření proti SQL inject.

Akceptované řešení
+20 Zkušeností
+1 bodů
Řešení problému
 
Nahoru Odpovědět 3.8.2015 19:08
Avatar
Michal Kuba
Redaktor
Avatar
Odpovídá na Martin Konečný (pavelco1998)
Michal Kuba:

Heuréka, díky moc! :) Fakt to funguje.. Proti injekcím to bude snad ok, kdyby se k tomu ale ještě někdo raději vyjádřil, budu klidnější :)

 
Nahoru Odpovědět 3.8.2015 19:23
Avatar
Martin Konečný (pavelco1998):

Jo, asi to bude lepší, s tímhle vyhledáváním moc zkušenost nemám :D

 
Nahoru Odpovědět 3.8.2015 19:45
Avatar
Michal Kuba
Redaktor
Avatar
Odpovídá na Martin Konečný (pavelco1998)
Michal Kuba:

Čas ukáže :) Musím teď nějak skloubit ošetření toho, že někdo zadá slovo, někdo město a někdo oboje..

Zatím to nefunguje, vrací to stránku ale bez inzerátu, i když zadané slovo existuje v datbázi

if($_POST){

             $_SESSION['filtr']= $filtr = array(
                                      'castTextu' => $_POST["castTextu"],
                      'castMesto' => $_POST["castMesto"]);
             $inzeraty= $castTextu && $castMesto;
             $castTextu=$spravceInzeratu->vratInzerat3($_SESSION['filtr']['castTextu']);
             $castMesto=$spravceInzeratu->vratInzerat4($_SESSION['filtr']['castMesto']);

             if(!empty($_SESSION['filtr'])){
            $this->data['inzeraty'] = $inzeraty;
             }
         }

model

public function vratInzerat3($parametry)
       {
               $ress= Db::dotazVsechny('
                       SELECT *
                       FROM `inzeraty`
                       WHERE text LIKE ?
                       ORDER BY `datum_vlozeni` DESC
   ',array("%{$parametry}%"));
               return $ress;
       }
       public function vratInzerat4($parametry)
       {
               $ress= Db::dotazVsechny('
                       SELECT *
                       FROM `inzeraty`
                       WHERE mesto LIKE ?
                       ORDER BY `datum_vlozeni` DESC
   ',array("%{$parametry}%"));
               return $ress;
       }

asi to bude složitější než se zdá, že? :(

 
Nahoru Odpovědět 3.8.2015 19:53
Avatar
Martin Konečný (pavelco1998):

K dynamickému skládání dotazů jsou super tzv. query buildery, s těmi pak můžeš udělat něco jako

$b = new SqlBuilder();
$b->addSelect("data, ...")->from("table");
if ($_POST["castTextu"]) {
  $b->where("text", $_POST["castTextu"]);
}
if ($_POST["castMesto"]) {
  $b->where("mesto", $_POST["castMesto"]);
}

Ve tvém případě asi budeš muset ten dotaz složit nějak ručně. Teď mě nenapadá žádný způsob, jak by se to dalo obejít pomocí operátorů nebo funkcí, ale možná to nějak jde.

Edit: a nepojmenovávej metody stejně, jen na konci jiné číslo :D když už, tak neni to sice moc hezký, ale je obvykle lepší třeba vratPodleMesta(), vratPodleMesta­NeboNazvu().

Editováno 3.8.2015 21:22
 
Nahoru Odpovědět  +1 3.8.2015 21:21
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 14 zpráv z 14.