Jump to content

não realiza a pesquisa


John Hebert Trindade
Go to solution Solved by John Hebert Trindade,

Recommended Posts

Bom dia a todos, estou desenvolvendo um projeto através de umas aulas com a CELKE.

Mas esta acontecendo uma coisa tão estranha e não consigo resolver, por isso estou pedindo a vossa ajuda.

fiz um formulário de pesquisa pelos distritos de Portugal, tenho um base de dados com todos os distritos cadastrado.

a pesquisa esta a funcionar não a 100% por os  distritos de "Faro" e "Castelo Branco" são os únicos que dão erro e não efectuam a pesquisa e por vezes tenho que fazer a pesquisa duas vezes para funcionar.

Quando não é encontrado ao invés de devolver a mensagem "Distrito não encontrado" não acontece nada.

Quem souber ajude me por favor.

Helpers AdmsRead:

<?php

namespace App\adms\helpers;

use PDO;
use PDOException;

/**
 * Classe genérica para selecionar registro no banco de dados
 *
 * @author John Trindade
 */
class AdmsRead extends AdmsConn
{
    /** @var string $select Recebe o QUERY */
    private string $select;

    /** @var array $values Recebe os valores que deve ser atribuidos nos link da QUERY com bindValue */
    private array $values = [];

    /** @var array $result Recebe os registros do banco de dados e retorna para a Models */
    private array|null $result;

    /** @var object $query Recebe a QUERY preparada */
    private object $query;

    /** @var object $conn Recebe a conexao com BD */
    private object $conn;

    /**
     * @return array Retorna o array de dados
     */
    function getResult(): array|null
    {
        return $this->result;
    }

    /** 
     * Recebe os valores para montar a QUERY.
     * Converte a parseString de string para array.
     * @param string $table Recebe o nome da tabela do banco de dados
     * @param string $terms Recebe os links da QUERY, ex: sts_situation_id =:sts_situation_id
     * @param string $parseString Recebe o valores que devem ser subtituidos no link, ex: sts_situation_id=1
     * 
     * @return void
     */
    public function exeRead(string $table, string|null $terms = null, string|null $parseString = null): void
    {
        if(!empty($parseString)){
            parse_str($parseString, $this->values);
        }

        $this->select = "SELECT * FROM {$table} {$terms}";
       
        $this->exeInstruction();
    }

    public function fullRead(string $query, string|null $parseString = null): void
    {
        $this->select = $query;
        if (!empty($parseString)) {
            parse_str($parseString, $this->values);
        }
        $this->exeInstruction();
    }

    private function exeInstruction():void
    {
        $this->connection();
        try{
            $this->exeParameter();
            $this->query->execute();
            $this->result = $this->query->fetchAll();
        }catch(PDOException $err){
            $this->result = null;
        }
    }
    
    private function connection():void
    {
       $this->conn = $this->connectDb();
       $this->query = $this->conn->prepare($this->select);
       $this->query->setFetchMode(PDO::FETCH_ASSOC);
    }

    private function exeParameter():void
    {
        if($this->values){
            foreach($this->values as $link => $value){
                
                if(($link == 'limit') or ($link == 'offset') or ($link == 'id')){
                    $value = (int) $value;
                }
                $this->query->bindValue(":{$link}", $value, (is_int($value) ? PDO::PARAM_INT : PDO::PARAM_STR));
            }
        }
    }
}

helpers Pagination:

<?php

namespace App\adms\helpers;

/**
 * Classe genérica para gerar a paginação
 *
 * @author John Trindade
 */
class AdmsPagination
{
    /** @var integer $page Recebe o numero da pagina que o usuario esta*/
    private int $page;
    /** @var integer $limitResult Recebe o limite de resultado*/
    private int $limitResult;
    /** @var integer $offset Recebe o calculo entre a quantidade de paginas e o limite de resultado*/
    private int $offset;
    /** @var string $query Recebe a query que será feita a paginação*/
    private string $query;
    /** @var string|null $parseString Recebe a parseString*/
    private string|null $parseString;
    /** @var array $resultBd Recebe o resultado que vem do banco de dados*/
    private array $resultBd;
    /** @var string|null $result Recebe o resultado TRUE ou FALSE*/
    private string|null $result;
    /** @var integer $totalPages Recebe o total de paginas*/
    private int $totalPages;
    /** @var integer $maxLinks Recebe o número maximo de paginas*/
    private int $maxLinks = 2;
    /** @var string $link Recebe o link da pagina*/
    private string $link;
    /** @var string|null $var Recebe a informação relacionada com a pagina*/
    private string|null $var;

    /** @return integer Recebe o resultado do calculo entre a quantidade de paginas e o linmite de resultado*/
    function getOffset(): int
    {
        return $this->offset;
    }

    /** @return string|null Recebe o resultado TRUE ou FALSE*/
    function getResult(): string|null
    {
        return $this->result;
    }

    /**
     * Metodo para criar o link da pagina
     *
     * @param string $link
     * @param string|null|null $var
     */
    function __construct(string $link, string|null $var = null)
    {
        $this->link = $link;
        $this->var = $var;
    }

    /**
     * Metodo recebe a pagina e o limite de resultado a ser exibido
     *
     * @param integer $page
     * @param integer $limitResult
     * @return void
     */
    public function condition(int $page, int $limitResult): void
    {
        $this->page = (int) $page ? $page : 1;
        $this->limitResult = (int) $limitResult;
        $this->offset = (int) ($this->page * $this->limitResult) - $this->limitResult;
    }

    /**
     * Metodo recebe a query que será feita a paginação e a parseString
     * Chama o helper AdmsRead para fazer a pesquisa no banco de dados
     * @param string $query
     * @param string|null|null $parseString
     * @return void
     */
    public function pagination(string $query, string|null $parseString = null): void
    {
        $this->query = (string) $query;
        $this->parseString = (string) $parseString;
        $count = new \App\adms\helpers\AdmsRead();
        $count->fullRead($this->query, $this->parseString);
        $this->resultBd = $count->getResult();
        $this->pageInstruction();
    }

    /**
     * Metodo faz o calculo do total de paginas 
     * Chama o metodo layoutPagination
     * @return void
     */
    private function pageInstruction(): void
    {
        $this->totalPages = (int) ceil($this->resultBd[0]['num_result'] / $this->limitResult);
        if ($this->totalPages >= $this->page) {
            $this->layoutPagination();
        } else {
            header("Location: {$this->link}");
        }
    }

    /**
     * Metodo com o layout da paginação que será exibida na view
     * @return void
     */
    private function layoutPagination(): void
    {
        $this->result = "<div class='content-pagination'>";
        $this->result .= "<div class='pagination'>";

        $this->result .= "<a href='{$this->link}{$this->var}'>Primeira</a>";

        for ($beforePage = $this->page - $this->maxLinks; $beforePage <= $this->page - 1; $beforePage++) {
            if ($beforePage >= 1) {
                $this->result .= "<a href='{$this->link}/$beforePage{$this->var}'>$beforePage</a>";
            }
        }

        $this->result .= "<a href='#' class='active'>{$this->page}</a>";

        for ($afterPage = $this->page + 1; $afterPage <= $this->page + $this->maxLinks; $afterPage++) {
            if ($afterPage <= $this->totalPages) {
                $this->result .= "<a href='{$this->link}/$afterPage{$this->var}'>$afterPage</a>";
            }
        }

        $this->result .= "<a href='{$this->link}/{$this->totalPages}{$this->var}'>Última</a>";

        $this->result .= "</div>";
        $this->result .= "</div>";
    }
}

model:

<?php

namespace App\adms\Models\distritos;

/**
 * Listar distritos do banco de dados
 */
class AdmsList
{
    /** @var bool $result Recebe true quando executar o processo com sucesso e false quando houver erro */
    private bool $result;

    /** @var array|null $resultBd Recebe os registros do banco de dados */
    private array|null $resultBd;

    /** @var int $page Recebe o número página */
    private int $page;

    /** @var int $page Recebe a quantidade de registros que deve retornar do banco de dados */
    private int $limitResult = 15;

    /** @var string|null $page Recebe a páginação */
    private string|null $resultPg;

    /** @var string|null $searchEmail Recebe o email do distrito */
    private string|null $searchDistrito;

    /** @var string|null $searchNameValue Recebe o nome do distrito */
    private string|null $searchNameValue;

    /**
     * @return bool Retorna true quando executar o processo com sucesso e false quando houver erro
     */
    function getResult(): bool
    {
        return $this->result;
    }

    /**
     * @return bool Retorna os registros do BD
     */
    function getResultBd(): array|null
    {
        return $this->resultBd;
    }

    /**
     * @return bool Retorna a paginação
     */
    function getResultPg(): string|null
    {
        return $this->resultPg;
    }

    /**
     * Metodo faz a pesquisa dos distritos na tabela adms_distritos e lista as informações na view
     * Recebe o paramentro "page" para que seja feita a paginação do resultado
     * @param integer|null $page
     * @return void
     */
    public function listDistritos(int $page = null): void
    {
        $this->page = (int) $page ? $page : 1;

        $pagination = new \App\adms\helpers\AdmsPagination(URLADM . 'list-distritos/index');
        $pagination->condition($this->page, $this->limitResult);
        $pagination->pagination("SELECT COUNT(dist.id) AS num_result FROM adms_distritos dist");
        $this->resultPg = $pagination->getResult();

        $listDistrito = new \App\adms\helpers\AdmsRead();
        $listDistrito->fullRead("SELECT dist.id, dist.name_distrito
                     FROM adms_distritos AS dist
                     ORDER BY dist.id ASC
                     LIMIT :limit OFFSET :offset", "limit={$this->limitResult}&offset={$pagination->getOffset()}");

        $this->resultBd = $listDistrito->getResult();
        if ($this->resultBd) {
            $this->result = true;
        } else {
            $_SESSION['msg'] = "<p class='alert-danger'>Erro: Nenhum Distrito encontrado!</p>";
            $this->result = false;
        }
    }

    /**
     * Metodo faz a pesquisa dos distritos na tabela adms_distritos e lista as informações na view
     * Recebe o paramentro "page" para que seja feita a paginação do resultado
     * Recebe o paramentro "search_distrito" para pesquisar o distrito atraves do nome
     * @param integer|null $page
     * @param string|null $search_distrito
     * @return void
     */
    public function listSearchDistrito(int $page = null, string|null $search_distrito): void
    {
        $this->page = (int) $page ? $page : 1;
        $this->searchDistrito = trim($search_distrito);

        $this->searchNameValue = "%" . $this->searchDistrito . "%";

        if ((!empty($this->searchDistrito))) {
            $this->searchUserName();
        } else {
            $this->listDistritos();
        }
    }

    /**
     * Metodo pesquisar pelo nome do distrito
     * @return void
     */
    public function searchUserName(): void
    {
        $pagination = new \App\adms\helpers\AdmsPagination(URLADM . 'list-distritos/index', "?search_name={$this->searchDistrito}");
        $pagination->condition($this->page, $this->limitResult);
        $pagination->pagination("SELECT COUNT(dist.id) AS num_result 
                             FROM adms_distritos dist
                             WHERE name_distrito LIKE :search_distrito", "search_distrito={$this->searchNameValue}");

        $this->resultPg = $pagination->getResult();

        $listUsers = new \App\adms\helpers\AdmsRead();
        $listUsers->fullRead("SELECT dist.id, dist.name_distrito 
                     FROM adms_distritos AS dist
                     WHERE dist.name_distrito LIKE :search_distrito 
                     ORDER BY dist.id ASC
                     LIMIT :limit OFFSET :offset", "search_distrito={$this->searchNameValue}&limit={$this->limitResult}&offset={$pagination->getOffset()}");

        $this->resultBd = $listUsers->getResult();
        if ($this->resultBd) {
            $this->result = true;
        } else {
            $_SESSION['msg'] = "<p class='alert-danger'>Erro: Nenhum distrito encontrado!</p>";
            $this->result = false;
        }
    }
}

Controler:

<?php

namespace App\adms\Controllers;

/**
 * Controller da página listar distritos
 * @author John Trindade <jht_pt@icloud.com>
 */
class ListDistritos
{
    /** @var array|string|null $data Recebe os dados que devem ser enviados para VIEW */
    private array|string|null $data;

    /** @var array|null $data Recebe os dados que devem do formulario */
    private array|null $dataForm;

    /** @var string|int|null  $page Recebe o numero da pagina que usuario esta */
    private string|int|null $page;

    /** @var string|null $searchDistrito Recebe o nome do distrito */
    private string|null $searchDistrito;

    public function index(string|int|null $page = null)
    {

        $this->page = (int) $page ? $page : 1;

        $this->dataForm = filter_input_array(INPUT_POST, FILTER_DEFAULT);

        $this->searchDistrito = filter_input(INPUT_GET, 'search_distrito', FILTER_DEFAULT);

        if (!empty($this->dataForm['SearchDistrito'])) {
            $listSearchDistrito = new \App\adms\Models\distritos\AdmsList();
            $listSearchDistrito->listSearchDistrito($this->page, $this->dataForm['search_distrito']);

            if ($listSearchDistrito->getResult()) {
                $this->data['list'] = $listSearchDistrito->getResultBd();
                $this->data['pagination'] = $listSearchDistrito->getResultPg();
            } else {
                $this->data['list'] = [];
                $this->data['pagination'] = "";
            }
            $this->data['form'] = $this->dataForm;
        } elseif (!empty($this->searchDistrito)) {
            $listSearchDistrito = new \App\adms\Models\distritos\AdmsList();
            $listSearchDistrito->listSearchDistrito($this->page, $this->searchDistrito);
            if ($listSearchDistrito->getResult()) {
                $this->data['list'] = $listSearchDistrito->getResultBd();
                $this->data['pagination'] = $listSearchDistrito->getResultPg();
            } else {
                $this->data['list'] = [];
                $this->data['pagination'] = "";
            }
            $this->data['form'] = $this->dataForm;
        } else {
            $listDistritos = new \App\adms\Models\distritos\AdmsList();
            $listDistritos->listDistritos($this->page);
            if ($listDistritos->getResult()) {
                $this->data['list'] = $listDistritos->getResultBd();
                $this->data['pagination'] = $listDistritos->getResultPg();
            } else {
                $this->data['list'] = [];
                $this->data['pagination'] = "";
            }
        }

        $this->data['sidebarActive'] = "list-distritos";

        $loadView = new \Core\ConfigView("adms/Views/distritos/list", $this->data);
        $loadView->loadView();
    }
}

Formulário:

<?php

if (isset($this->data['form'])) {
    $valorForm = $this->data['form'];
}
?>

<!-- Inicio do conteudo do Administrativo -->
<div class="wrapper">
    <div class="row">
        <!-- Inicio menu pesquisa -->
        <div class="top-list">
            <form method="POST" action="">
                <div class="row-input-search">
                    <?php
                    $search_distrito = "";
                    if (isset($valorForm['search_distrito'])) {
                        $search_distrito = $valorForm['search_distrito'];
                    }
                    ?>
                    <div class="column">
                        <label class="title-input-search">Pesquisar Distrito: </label>
                        <input type="text" name="search_distrito" id="search_distrito" class="input-search" placeholder="Pesquisar pelo nome do Distrito..." value="<?php echo $search_distrito; ?>" autofocus>
                    </div>

                    <div class="column margin-top-search">
                        <button type="submit" name="SearchDistrito" class="btn-info" value="Pesquisar">Pesquisar</button>
                    </div>
                </div>
            </form>
        </div>

        <div class="content-adm-alert">
            <?php
            if (isset($_SESSION['msg'])) {
                echo $_SESSION['msg'];
                unset($_SESSION['msg']);
            }
            ?>
        </div>

        <!-- Inicio da Tabela Listar -->
        <table class="table-list">
            <thead class="list-head">
                <tr>
                    <th class="list-head-content table-md-none">ID</th>
                    <th class="list-head-content">Distrito</th>
                </tr>
            </thead>
            <tbody class="list-body">
                <?php
                foreach ($this->data['list'] as $distritos) {
                    extract($distritos);
                ?>
                    <tr>
                        <td class="list-body-content table-md-none"><?php echo $id; ?></td>
                        <td class="list-body-content"><?php echo $name_distrito; ?></td>
                    </tr>
                <?php } ?>
            </tbody>
        </table>
        <!-- Final da Tabela Listar -->
        <!-- Inicio da Paginação -->
        <?php
        echo $this->data['pagination'];
        ?>
        <!-- Final da Paginação -->

    </div>
</div>
<!-- Final do conteudo do Administrativo-->

 

Link to comment
Share on other sites

Boa noite, descobri mais uma coisa.

se eu altero o link da pesquisa para o valor correcto da pesquisa funciona.

alterei na model as seguinte linhas e funcionou

como estava
129 WHERE distr.name_distrito LIKE :search_distrito 
alterado para
129 WHERE distr.name_distrito LIKE 'faro'


como estava
131 LIMIT :limit OFFSET :offset", "search_distrito={$this->searchNameValue}&limit={$this->limitResult}&offset={$pagination->getOffset()}");
alterado para
131 LIMIT :limit OFFSET :offset", "limit={$this->limitResult}&offset={$pagination->getOffset()}");

 

Link to comment
Share on other sites

Isso não tem nada a ver com o sistema operativo, poderá ter que vez com, por exemplo, encoding.
Se trocares

$this->searchNameValue = "%" . $this->searchDistrito . "%";

por

$this->searchNameValue = "%faro%";

Já obténs o que pretendes?

10 REM Generation 48K!
20 INPUT "URL:", A$
30 IF A$(1 TO 4) = "HTTP" THEN PRINT "400 Bad Request": GOTO 50
40 PRINT "404 Not Found"
50 PRINT "./M6 @ Portugal a Programar."

 

Link to comment
Share on other sites

Bom dia M6, foi desta forma que descobri o ocorrido, eu fiz essa alteração que esta a dizer, mas eu quero que a pesquisa seja dinâmica, ou seja, o $this->searchDistrito recebe a palavra que foi digitada pelo usuário no formulário.

Da forma que esta a dizer ficaria fixa.

Edited by John Hebert Trindade
Link to comment
Share on other sites

  • 2 weeks later...
  • Solution

O professor do curso que estou a fazer respondeu me a essa dúvida, estou postando aqui para que todos tenham conhecimento.

"...O erro de não converter corretamente ou reconhecer primeiro por cento "%" é regra da função "parse_str".
Para corrigir é necessário alterar de parse_str.

No arquivo "Models/helper/AdmsRead.php", alterar de: parse_str($parseString, $this->values);

Para: 

$pairs = explode('&', $parseString);
foreach ($pairs as $pair) {
list($key, $value) = explode('=', $pair);
$this->values[$key] = $value;
} " é da função "parse_str"

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.