Lançado Adianti Framework 7.6!
Clique aqui para saber mais
Refletindo o uso de URLs amigáveis no Adianti O Adianti Framework foi concebido para auxiliar no desenvolvimento de sistemas em PHP. Justificado por essa questão, o uso de URLs amigáveis nunca foi o objetivo do Framework. Porém, recentemente a comunidade tem aumentado a pressão para o seu uso. Aproveitando esse momento, julgou-se como pertinente publicar esse artigo utilizando como base um estudo feito por esse autor ano passado (2014). ...
GF
Refletindo o uso de URLs amigáveis no Adianti  
O Adianti Framework foi concebido para auxiliar no desenvolvimento de sistemas em PHP. Justificado por essa questão, o uso de URLs amigáveis nunca foi o objetivo do Framework. Porém, recentemente a comunidade tem aumentado a pressão para o seu uso. Aproveitando esse momento, julgou-se como pertinente publicar esse artigo utilizando como base um estudo feito por esse autor ano passado (2014).

Durante o desenvolvimento de um sistema a equipe está focada principalmente nas regras de negócio. Após o sistema ficar pronto a equipe começa a ver os problemas: A falta de usabilidade e o fluxo de navegação (foco desse artigo). A questão de usabilidade vai de como foi arquitetado o sistema, já o fluxo de navegação depende da redundância de navegação (várias formas de chegar ao mesmo ponto), do número de etapas a serem seguidas para resolver um problema, e finalmente as URLs. As URLs, como o próprio nome já diz, são a forma de localizar recursos na web. Isso significa que os recursos do seu sistema vão ser localizados através dela. Então, pensar em URLs amigáveis é importante sim.

Existem casos em que áreas do sistema não apresentam restrição de acesso. O usuário vai acessar essa parte do sistema como se fosse um site. Provavelmente essa parte do sistema será uma descrição do que se trata o sistema, poderá ser uma área onde são exibidos os planos que poderão ser contratados, ou quem sabe uma área onde o usuário poderá cria a sua conta. Não importa, qualquer sistema terá uma área sem restrição. A questão é: Como ocorrem os acessos a essas áreas? Via URL! Então devemos tratar elas de forma mais interessante do que abusar de query strings.

Como já foi descrito acima, esses são resultados de um estudo de 2014, válido apenas para as versões 1.02 e 1.03. Durante a execução desse estudo foram alterados todos os arquivos que tratam a leitura de query strings, além disso, foi criada uma classe para efetuar a decodificação das URLs amigáveis. Concluído o estudo, foi possível desenvolver sistemas usando URLs amigáveis no Adianti Framework.
As URLs seguiram o padrão: www.sistema.com.br/controller/método/var/var/var. Além de permitir a associação de chave/valor, podendo a URL assumir a seguinte configuração: www.sistema.com.br/controller/método/key/var/key/var. Para atingir esse resultado, foi necessário alterar a classe TCoreApplication e nela instanciou-se a classe decodificadora de ULs amigáveis, para então essa retornar os dados que a TCoreApplication necessita. O resultado pode ser observado no trecho de código abaixo:

<php
class TCoreApplication
{
public static function run($debug = FALSE)
{
// get TURI instance;
$turi = TURI::getInstance();

$class = $turi->getClass() ? $turi->getClass() : 'meus-clientes';
$static = isset($_REQUEST['static']) ? $_REQUEST['static'] : '';
$method = $turi->getMethod() ? $turi->getMethod() : '';
$vars = $turi->getVars();
?>

Nota-se que primeiramente é pego uma instância de TURI, e em seguida, são passadas as informações que a TCoreApplication necessita para operação. Abaixo pode ser observado o código da classe TURI.

  1. <?php
  2. /**
  3.  * TURI utility class
  4.  * Copyright (c) 2010-2014 Guilherme Faht
  5.  * @author  Guilherme Faht <guilherme [at] catcom.com.br>
  6.  * @version 1.0, 2014-02-23
  7.  */
  8. class TURI
  9. {
  10.     
  11.     private static $instance;
  12.     private $uri_string;
  13.     private $segments = array();
  14.     
  15.     /**
  16.      * Construtor.
  17.      */
  18.     private function __construct(){}
  19.     
  20.     /**
  21.      * Método detect_uri()
  22.      * Faz a detecção do uri correto.
  23.      */    
  24.     private function detect_uri()
  25.     {
  26.         if ( ! isset($_SERVER['REQUEST_URI']) OR ! isset($_SERVER['SCRIPT_NAME']))
  27.         {
  28.             return '';
  29.         }
  30.         $uri $_SERVER['REQUEST_URI'];
  31.         if (strpos($uri$_SERVER['SCRIPT_NAME']) === 0)
  32.         {
  33.             $uri substr($uristrlen($_SERVER['SCRIPT_NAME']));
  34.         }
  35.         elseif (strpos($uridirname($_SERVER['SCRIPT_NAME'])) === 0)
  36.         {
  37.             $uri substr($uristrlen(dirname($_SERVER['SCRIPT_NAME'])));
  38.         }
  39.         if (strncmp($uri'?/'2) === 0)
  40.         {
  41.             $uri substr($uri2);
  42.         }
  43.         $parts preg_split('#\?#i'$uri2);
  44.         $uri $parts[0];
  45.         if (isset($parts[1]))
  46.         {
  47.             $_SERVER['QUERY_STRING'] = $parts[1];
  48.             parse_str($_SERVER['QUERY_STRING'], $_GET);
  49.         }
  50.         else
  51.         {
  52.             $_SERVER['QUERY_STRING'] = '';
  53.             $_GET = array();
  54.         }
  55.         if ($uri == '/' || empty($uri))
  56.         {
  57.             return '/';
  58.         }
  59.         $uri parse_url($uriPHP_URL_PATH);
  60.         return str_replace(array('//''../'), '/'trim($uri'/'));
  61.     }
  62.     
  63.     /**
  64.      * Método filter_uri()
  65.      * Filtra a uri.
  66.      */
  67.     private function filter_uri($str)
  68.     {
  69.         if ($str != '')
  70.         {
  71.             if ( ! preg_match("|^[".str_replace(array('\\-''\-'), '-'preg_quote('a-z 0-9~%.:_\-''-'))."]+$|i"$str))
  72.             {
  73.                 trigger_error('Caracteres inválidos na uri.');
  74.             }
  75.         }
  76.         $bad    = array('$''('')''%28''%29');
  77.         $good    = array('&#36;''&#40;''&#41;''&#40;''&#41;');
  78.         return str_replace($bad$good$str);
  79.     }
  80.     
  81.     /**
  82.      * Método getInstance()
  83.      * Retorna a instância de TURI.
  84.      */
  85.     public static function getInstance()
  86.     {
  87.         if(!self::$instance){
  88.             
  89.             self::$instance = new TURI();
  90.             self::$instance->explode_segments();
  91.         }
  92.         
  93.         return self::$instance
  94.     }
  95.     
  96.     /**
  97.      * Método explode_segments()
  98.      * Popula os segmentos disponíveis.
  99.      */
  100.     private function explode_segments()
  101.     {
  102.         foreach (explode("/"preg_replace("|/*(.+?)/*$|""\\1"$this->getURI())) as $val)
  103.         {
  104.             $val trim($this->filter_uri($val));
  105.             if ($val != '')
  106.             {
  107.                 $this->segments[] = $val;
  108.             }
  109.         }
  110.     }
  111.     
  112.     /**
  113.      * Método getURI()
  114.      * Retorna a URI.
  115.      */
  116.     public function getURI()
  117.     {    
  118.         if(!$this->uri_string)
  119.         {
  120.            $this->uri_string $this->detect_uri(); 
  121.         }
  122.         return $this->uri_string;
  123.     }
  124.     
  125.     /**
  126.      * Método getClass
  127.      * Retorna a classe invocada.
  128.      */
  129.     public function getClass(){
  130.         
  131.         // Rotas disponíveis.        
  132.         $routes = array(
  133.             'cadastro-cliente'  => 'ClienteForm',
  134.             'listagem-cliente'  => 'ClienteList',
  135.             'relatorio-cliente' => 'ClienteReport'           
  136.         ); 
  137.         
  138.         if(isset($this->segments[0])){
  139.             
  140.             if(isset($routes[$this->segments[0]]))
  141.             {
  142.                 return $routes[$this->segments[0]];
  143.             }
  144.             
  145.             return $this->segments[0];
  146.         }
  147.         return NULL;
  148.     }
  149.     
  150.     /**
  151.      * Método getMethod()
  152.      * Retorna o método a ser invocado.
  153.      */
  154.     public function getMethod(){
  155.         
  156.         if(isset($this->segments[1])){
  157.             return $this->segments[1];
  158.         }
  159.         return NULL;
  160.     }
  161.     
  162.     /**
  163.      * Método getVars()
  164.      * Retorna o array de variáveis.
  165.      */
  166.     public function getVars(){
  167.                 
  168.         if(count($this->segments) >= 3){
  169.             
  170.             $segments $this->segments;
  171.             array_shift($segments);
  172.             array_shift($segments);
  173.             
  174.             $vars = array();
  175.             
  176.             for($i=0$i<count($segments); $i++){
  177.                 
  178.                 if(isset($segments[$i+1])){
  179.                     $vars[$segments[$i]] = $segments[$i+1];
  180.                     $i++;
  181.                 } else {
  182.                     array_push($vars,$segments[$i]);
  183.                 }        
  184.             } 
  185.             
  186.             return $vars;
  187.         }
  188.         return NULL;
  189.     }
  190. }
  191. ?>


Além da criação da classe TURI, foi necessário fazer profundas alterações na classe TAction e na Classe TDataGridAction, pois essas precisaram gerar requisições via URLs amigáveis conforme o padrão descrito acima.
Sendo assim, foi o objetivo desse artigo permitir uma melhor aplicação de URLs amigáveis usando o Adianti Framework. Qualquer dúvida ou sugestão fique a vontade em expressar a sua opinião. Afinal, criticas e sugestões são os recursos para propiciar mudanças.

Pacotão Dominando o Adianti Framework 7
O material mais completo de treinamento do Framework.
Curso em vídeo aulas + Livro completo + Códigos fontes do projeto ERPHouse.
Conteúdo Atualizado! Versão 7.4


Dominando o Adianti 7 Quero me inscrever agora!

Comentários (2)


JC

Boa noite.

Desculpa, sou novato no uso desta ferramenta (Adianti) e também em php, como aplicar este código acima na framework?

Grato.
GF

Boa noite. Ele objetiva construir URLs amigáveis. Mas esse código era para a versão 2 do framework.
Abraço.