sexta-feira, 28 de junho de 2013

Script padrão para bancos de dados Mysql em linguagem PHP - XI

A classe paramLine

No post anterior avisamos que iríamos explicar a classe paramLine, responsável pelo ajuste dos delimitadores, valores e da tag HTML de cada campo a ser gravado no campo de dados para a ação de inclusão (addsave).

Código:

      // Classe usada para as ações: add, addsave e list
      class paramLine{
public $delimitador;
public $valorfinal;
public $tipocampo;
public $taginput;
function __construct($arranjo,$linha,$valorparam){
 $valor = $valorparam;
 $this->valorfinal = $valorparam;
 $this->delimitador = $arranjo[$linha][7];
 $tipo = strtolower($arranjo[$linha][4]);
 $this->tipocampo = $tipo;
 $sTipo = $tipo;
 $inp = "<input";
 $this->taginput = $inp;
 switch ($tipo){
   case "select":
     $inp = "<select";
     $deli = "'";
     break;
   case "textarea":
     $inp = "<textarea";
     $deli = "'";
     break;
   case "":
     $deli = "";
     $sTipo = "number";
     break;
   case "'":
     $deli = "'";
     $sTipo = "text";
     break;
   case "email":
     $deli = "'";
     break;
   case "hidden":
     $deli = "'";
     $sTipo = "hidden";
     break;
   case "pwd":
     $deli = "";
     $sTipo = "password";
     $valor = "PASSWORD('" . $valor . "')";
     break;
   case "#":
     $deli = "'";
     $sTipo = "date";
     if( preg_match("/\d{1,2}[\/|\-]\d{1,2}[\/|\-]\d{4}/", $valor, $matches) ){
$dt = substr($valor,6,4) . "-" . substr($valor,3,2) . "-" . substr($valor,0,2);
} else {
$dt = $valor;
}
     $valor = $dt;
     break;
   default:
     $sTipo = "unknown";
     $deli = "'";
     break;
   }
   $this->delimitador = $deli;
   $this->valorfinal = $valor;
   $this->tipocampo = $sTipo;
   $this->taginput = $inp;
 }
function getDelimitador(){
 return $this->delimitador;
 }
function getValorfinal(){
 return $this->valorfinal;
 }
function getTipocampo(){
 return $this->tipocampo;
 }
}

Explicação

No início da classe são definidos os quatro parâmetros para saída:

public $delimitador;
public $valorfinal;
public $tipocampo;
public $taginput;

Em seguida vem o construtor, com a seguinte sintaxe:

      function __construct($arranjo,$linha,$valorparam){

A ordem dos parâmetros deve ser A MESMA na definição do construtor e na instanciação de um objeto desta classe.

Ajuste inicial

  $valor = $valorparam;
  $this->valorfinal = $valorparam;
  $this->delimitador = $arranjo[$linha][7];
  $tipo = strtolower($arranjo[$linha][4]);
  $this->tipocampo = $tipo;
  $sTipo = $tipo;
  $inp = "<input";
  $this->taginput = $inp;

Estas linhas armazenam os conteúdos iniciais dos atributos do objeto, tomando o cuidado de resguardar os valores iniciais.

Testes

Para cada tipo possível de dados dos campos, será feito um tratamento diferente:

select

    case "select":
      $inp = "<select";
      $deli = "'";
      break;

textarea

    case "textarea":
      $inp = "<textarea";
      $deli = "'";
      break;

Numérico

    case "":
      $deli = "";
      $sTipo = "number";
      break;

Texto simples

    case "'":
      $deli = "'";
      $sTipo = "text";
      break;

Email

    case "email":
      $deli = "'";
      break;

Campo escondido

    case "hidden":
      $deli = "'";
      $sTipo = "hidden";
      break;

Senha

    case "pwd":
      $deli = "";
      $sTipo = "password";
      $valor = "PASSWORD('" . $valor . "')";
      break;

Data

    case "#":
      $deli = "'";
      $sTipo = "date";
      if( preg_match("/\d{1,2}[\/|\-]\d{1,2}[\/|\-]\d{4}/", $valor, $matches) ){
$dt = substr($valor,6,4) . "-" . substr($valor,3,2) . "-" . substr($valor,0,2);
} else {
$dt = $valor;
}
      $valor = $dt;
      break;

Métodos get da classe

function getDelimitador(){
  return $this->delimitador;
  }
function getValorfinal(){
  return $this->valorfinal;
  }
function getTipocampo(){
  return $this->tipocampo;
  }

Script padrão para bancos de dados Mysql em linguagem PHP - X

A ação addsave

Depois de preenchido o formulário de inclusão na ação add, os conteúdos dos campos se transformam em entidades textuais adequadas para um tratamento que possibilite a sua gravação, ou seja, de uma disposição gráfica vamos transformar os conteúdos em disposição de registro de banco de dados.

Nesta ação, não precisamos fazer a checagem de permissão, pois esta já foi feita na ação add. Se alguém tentar construir a ação addsave passo a passo, em outra script, deturpando o seu sentido, vai ter muito trabalho, e praticamente terá que fazer outra script, passar por cima da segurança do banco, etc. Se você quiser implementar segurança adicional, já tem o exemplo da operação add, e fica a seu critério fazê-lo.

O código

 case "addsave":
   $operation = $operAddSave;
   $description = $descAddSave;
   require("libCabecalhoPadrao.php");
   $deli = "";
   $valor = NULL;
   $x = 0;
   $campos = "";
   $valores = "";
   // Loop no esquema da estrutura de dados
   for($x=1;$x<$NoCampos;$x++){
$valor = $_POST[$arr[$x][0]];
// Ajuste do tipo, valor, delimitador e tag do campo
$pl = new paramLine($arr,$x,$valor);
$sTipo = $pl->tipocampo;
$valor = $pl->valorfinal;
$deli  = $pl->delimitador;
if( $x == 1 ){
 $campos = $arr[$x][0];
 $valores = $deli . $valor . $deli;
 } else {
 if( $valor != "" && $valor != 0 ){
   $campos = $campos . "," . $arr[$x][0];
   $valores = $valores . "," . $deli . $valor . $deli;
   }
 }
}
   $strSQL = "INSERT INTO " . $tabela . "(";
   $strSQL = $strSQL . $campos . ") VALUES (" . $valores . ")";
   include 'Conexao_banco.php';
   mysqli_query($conn, $strSQL) or die("<br><span class=bdOK>Insert Operation 
Unsuccessfull.</span>");
   include 'Conexao_banco_close.php';
   echo $msgAdd;
   break;

Preparação Gráfica

case "addsave":
   $operation = $operAddSave;
   $description = $descAddSave;
   require("libCabecalhoPadrao.php");
   $deli = "";
   $valor = NULL;
   $x = 0;
   $campos = "";
   $valores = "";

A primeira linha direciona corretamente a ação da script conforme o parâmetro recebido e manipulado nesta estrutura switch. Em seguida são alimentados os parâmetros $operation e $description para chamada do código do require "libCabecalhoPadrao.php".

As demais variáveis preparam lugar para receber parâmetros essenciais para manipulação dos registros:


  • Delimitador: $deli
  • Valor: $valor
  • Contador: $x
  • Campos: $campos
  • Valores: $valores


Loop de leitura e interpretação do SCHEMA

   // Loop no esquema da estrutura de dados
   for($x=1;$x<$NoCampos;$x++){
$valor = $_POST[$arr[$x][0]];
// Ajuste do tipo, valor, delimitador e tag do campo
$pl = new paramLine($arr,$x,$valor);
$sTipo = $pl->tipocampo;
$valor = $pl->valorfinal;
$deli  = $pl->delimitador;
if( $x == 1 ){
 $campos = $arr[$x][0];
 $valores = $deli . $valor . $deli;
 } else {
 if( $valor != "" && $valor != 0 ){
   $campos = $campos . "," . $arr[$x][0];
   $valores = $valores . "," . $deli . $valor . $deli;
   }
 }
}

O indexador $x varia de 1 (o campo Id não precisa ser trabalhado no INSERT, pois assumirá um valor controlado pelas triggers internas de autonumeração do MySQL). Este indexador comanda a busca nas variáveis postadas ($_POST[$arr[$x][0]]) do valor que veio de cada campo do formulário. Em seguida é instanciado o objeto $pl através dos parâmetros $arr, $x e $valor. O parâmetro $arr é necessário para que se encontre as referências de tamanho, nome do campo, etc. O parâmetro $x informa em que índice está o loop. E o parâmetro $valor traz o conteúdo que foi preenchido no formulário (alimentado pela variável correta do POST).

A classe paramLine

Esta classe faz todas as checagens de características de cada campo com o fim de corrigir o delimitador (de acordo com o tipo do mesmo) e também corrigir o valor, pois este pode ser uma data, uma senha, um email,  etc.

Código da classe

Discutiremos esta classe no próximo post deste blog.

Retorno da classe

Quando a chamada à classe é feita, recebemos três parâmetros corrigidos:

$sTipo = $pl->tipocampo;
$valor = $pl->valorfinal;
$deli  = $pl->delimitador;

Estes novos parâmetros é que irão pautar as próximas manipulações.

Construção da sentença SQL

Existe uma diferença entre o primeiro parâmetro a ser colocado na sentença SQL, por causa da vírgula que sucede cada nome ou valor de cada um deles. Por isto é preciso fazer a estrutura condicional:

      // Primeiro campo
              if( $x == 1 ){
  $campos = $arr[$x][0];
  $valores = $deli . $valor . $deli;
  } else {
                  // Demais campos
                  // Verifica se o campo foi preenchido. Só se estiver é que vai compor o SQL,
                  // senão é desprezado
  if( $valor != "" && $valor != 0 ){
    $campos = $campos . "," . $arr[$x][0];
    $valores = $valores . "," . $deli . $valor . $deli;
    }
  }

Construção final da sentença SQL de INSERT

   $strSQL = "INSERT INTO " . $tabela . "(";
   $strSQL = $strSQL . $campos . ") VALUES (" . $valores . ")";

A variável $strSQL vai concatenar a sintaxe natural, os nomes dos campos e os conteúdos do INSERT com os delimitadores devidamente normalizados.

Execução da sentença SQL

   include 'Conexao_banco.php';
   mysqli_query($conn, $strSQL) or die("<br><span class=bdOK>Insert Operation
Unsuccessfull.</span>");
   include 'Conexao_banco_close.php';

Emissão da mensagem de Inclusão

   echo $msgAdd;

A mensagem contida em $msgAdd está no include ExemploDefinicao.inc.







segunda-feira, 24 de junho de 2013

Script padrão para bancos de dados Mysql em linguagem PHP - IX

As ações da Engine genérica de manipulação de Bancos de Dados

Conforme o post III desta série sobre a Engine genérica, são 7 as ações possíveis sobre os registros de uma tabela para qualquer tipo de Banco de Dados.

Vamos analisar uma a uma, linha a linha. A primeira é ...

A ação add

Esta ação (1) exibe um formulário dinâmico cujo design é definido pela análise do arranjo de campos definido através do conteúdo do include "ExemploDefinicao.inc", e (2) aguarda o pressionamento do botão de submissão do formulário, para (3) efetuar a consistência campo a campo, e (4) enviar os conteúdos para a ação "addsave". Esta e todas as outras ações estão dentro do escopo da instrução switch do PHP. Vamos mostrar aqui o código completo:

case "add":
     // Verifica permissão para a operação
     if( $permiteAdd ){
       // Titulos e cabeçalhos
       $operation = $operAdd;
       $description = $descAdd;
       require("libCabecalhoPadrao.php");
       ?>
       <h2 class=tit>NOVO REGISTRO</h2>
       <h5 class=help>Entrada de Informações. Campos com <img src="Preencha.png"> são obrigatórios</h5>
       <?php
       openQuadro();
       // Formulário de Preenchimento
       echo "<form method=post action=?action=addsave&estilo=" . $_GET['estilo'] . " OnSubmit=\"return manda(this);\">";
       echo "<table border=0 cellspacing=0>";
       // Loop no esquema da estrutura de dados
       for($x=0;$x<$NoCampos;$x++){
  $sTipo = "";
  $inp = "<input";
  echo "<tr><td><label>" . $arr[$x][1] . "</label></td>";
  echo "<td>";
  // Ajuste do tipo, valor e tag do campo
  $pl = new paramLine($arr,$x,"");
  $inp = $pl->taginput;
  $sTipo = $pl->tipocampo;
  echo $inp;
  echo " name=" . $arr[$x][0] . " id=" . $arr[$x][0];
  // Obrigatoriedade do campo
  if( $arr[$x][5] == "S" && $x > 0 ){
    echo " class=obr ";
    }
  // Tipos de tags
  $tamCampo = $arr[$x][2];
  $tamMax = $arr[$x][3];
  if ( strtolower($inp) == "<select" ) {
      echo ">" . $arr[$x][6];
    } elseif ( strtolower($inp) == "<textarea" ) {
      echo " cols=" . $arr[$x][2] . " rows=" . number_format($tamMax/$tamCampo,0,'.','') . ">";
    } elseif ( strtolower($inp) == "<input" ){
      if( $sTipo == "number" || $sTipo == "email" ){ $sTipo = "text"; }
      echo " type=" . $sTipo . " size=" . $tamCampo ." maxlength=" . $tamMax . " value=" . $arr[$x][8] . ">";
    }
  if ( $inp == "<textarea" ) {
    echo "</textarea>";
    }
  if ( $inp == "<select" ) {
    echo "</select>";
    }
  echo "</td><td><span class=msg>" . $arr[$x][7] . "</span></td></tr>";
  }
       echo "<tr><td colspan=3 align=center><input class=post type=submit value=\"" . $btnAdd . "\"></td>";
       echo "</table>"; 
       echo "</form>";
       closeQuadro();
       } else {
       echo $msgPermissao;
       }
     break;
Explicação:

   // Verifica permissão para a operação
   if( $permiteAdd ){
            .
            .
            .
                } else {
     echo $msgPermissao;
     }

O código desta ação fica condicionado a uma verificação no parâmetro $permiteAdd, declarado no include ExemploDefinicao.inc. Se lá estiver declarado um valor "S" para este parâmetro, o restante da ação será permitido, senão será mostrada a mensagem $msgPermissao, também declarada no include de que falamos aqui.

       // Titulos e cabeçalhos
       $operation = $operAdd;
       $description = $descAdd;
       require("libCabecalhoPadrao.php");
       ?>
       <h2 class=tit>NOVO REGISTRO</h2>
       <h5 class=help>Entrada de Informações. Campos com <img src="Preencha.png"> são obrigatórios</h5>
       <?php
       openQuadro();

As variáveis $operation e $description são parâmetros do HTML contido no include libCabecalhoPadrao.php, cujo código repetiremos aqui:

 <div class=h2><div class="btn b1"><?= $titulo ?> - <?= $operation ?></div></div>
  <div class=h3><div class="btn b2"><?= $description ?>&nbsp;[<?= $_SERVER['REMOTE_ADDR'] .'-' . $_SERVER['SERVER_ADDR'] ?>]
  <a class="btn" style="margin-left:50px;" href="?estilo=<?= $_GET['estilo'] ?>"><span class="btn a">TELA INICIAL</span></a>
  </div>
  </div>

O cabeçalho é feito à base de DIVs, pois são os containers mais flexíveis do HTML.

Vamos ao trecho seguinte:

       // Formulário de Preenchimento
       echo "<form method=post action=?action=addsave&estilo=" . $_GET['estilo'] . " OnSubmit=\"return manda(this);\">";
       echo "<table border=0 cellspacing=0>";
       // Loop no esquema da estrutura de dados
       for($x=0;$x<$NoCampos;$x++){
  $sTipo = "";
  $inp = "<input";
  echo "<tr><td><label>" . $arr[$x][1] . "</label></td>";
  echo "<td>";
  // Ajuste do tipo, valor e tag do campo
  $pl = new paramLine($arr,$x,"");
  $inp = $pl->taginput;
  $sTipo = $pl->tipocampo;
  echo $inp;
  echo " name=" . $arr[$x][0] . " id=" . $arr[$x][0];
  // Obrigatoriedade do campo
  if( $arr[$x][5] == "S" && $x > 0 ){
    echo " class=obr ";
    }
  // Tipos de tags
  $tamCampo = $arr[$x][2];
  $tamMax = $arr[$x][3];
  if ( strtolower($inp) == "<select" ) {
      echo ">" . $arr[$x][6];
    } elseif ( strtolower($inp) == "<textarea" ) {
      echo " cols=" . $arr[$x][2] . " rows=" . number_format($tamMax/$tamCampo,0,'.','') . ">";
    } elseif ( strtolower($inp) == "<input" ){
      if( $sTipo == "number" || $sTipo == "email" ){ $sTipo = "text"; }
      echo " type=" . $sTipo . " size=" . $tamCampo ." maxlength=" . $tamMax . " value=" . $arr[$x][8] . ">";
    }
  if ( $inp == "<textarea" ) {
    echo "</textarea>";
    }
  if ( $inp == "<select" ) {
    echo "</select>";
    }
  echo "</td><td><span class=msg>" . $arr[$x][7] . "</span></td></tr>";
  }
       echo "<tr><td colspan=3 align=center><input class=post type=submit value=\"" . $btnAdd . "\"></td>";
       echo "</table>"; 
       echo "</form>";

Este trecho desenha o formulário de entrada dos campos a serem preenchidos por meio do loop:

for($x=0;$x<$NoCampos;$x++){

   .

   .

   .

   }

O parâmetro $NoCampos é configurado no include ExemploDefinicao.inc.

Tratamento dos campos

  $sTipo = "";
  $inp = "<input";
  echo "<tr><td><label>" . $arr[$x][1] . "</label></td>";
  echo "<td>";
  // Ajuste do tipo, valor e tag do campo
  $pl = new paramLine($arr,$x,"");
  $inp = $pl->taginput;
  $sTipo = $pl->tipocampo;
  echo $inp;
  echo " name=" . $arr[$x][0] . " id=" . $arr[$x][0];
  // Obrigatoriedade do campo
  if( $arr[$x][5] == "S" && $x > 0 ){
    echo " class=obr ";
    }
  // Tipos de tags
  $tamCampo = $arr[$x][2];
  $tamMax = $arr[$x][3];
  if ( strtolower($inp) == "<select" ) {
      echo ">" . $arr[$x][6];
    } elseif ( strtolower($inp) == "<textarea" ) {
      echo " cols=" . $arr[$x][2] . " rows=" . number_format($tamMax/$tamCampo,0,'.','') . ">";
    } elseif ( strtolower($inp) == "<input" ){
      if( $sTipo == "number" || $sTipo == "email" ){ $sTipo = "text"; }
      echo " type=" . $sTipo . " size=" . $tamCampo ." maxlength=" . $tamMax . " value=" . $arr[$x][8] . ">";
    }
  if ( $inp == "<textarea" ) {
    echo "</textarea>";
    }
  if ( $inp == "<select" ) {
    echo "</select>";
    }
  echo "</td><td><span class=msg>" . $arr[$x][7] . "</span></td></tr>";
  }

A chave para a construção das entradas dos campos é o tipo do campo ($sTipo). Ele define o delimitador e as alterações que serão feitas no valor digitado para o campo, bem como a consistência a ser efetuada no mesmo.

Fechamento do formulário

       echo "<tr><td colspan=3 align=center><input class=post type=submit value=\"" . $btnAdd . "\"></td>";
       echo "</table>"; 
       echo "</form>";
       closeQuadro();
       } else {
       echo $msgPermissao;
       }

À conclusão do formulário segue-se a mensagem de falta de permissão para a operação que fecha o:

if( $permiteAdd ){

Conclusão da ação

A conclusão desta ação é a instrução:

break; 


quinta-feira, 20 de junho de 2013

Como utilizar o FCKeditor em uma script PHP no Linux

O pacote do FCKeditor ocupa uma pasta (diretório) no Linux. Você pode colocar esta pasta sob o diretório /var/www, ou em qualquer outro lugar fazendo o correspondente link simbólico. A escolha é sua.

A script que vai instanciar a classe FCKeditor em PHP DEVERÁ ESTAR NO MESMO DIRETÓRIO DO  FCKeditor.

Um exemplo é a script a seguir:

<html>
    <head>
      <meta http-equiv="Content-Type" content="text/html" charset="utf-8"/>
      <title><?= __FILE__ ?> - FCKEditor</title>
      <style>
      </style>
      <?php
      require("fckeditor_php5.php");
      ?>
    </head>
    <body>
      <?php
 $editor = new FCKEditor('FCKEditor');
 $editor->Create();
      ?>
    </body>
</html>

Este é o código mínimo para instanciar o FCKeditor.

quarta-feira, 19 de junho de 2013

Script padrão para bancos de dados Mysql em linguagem PHP - VIII

Abertura e fechamento da conexão com o banco

Conexao_banco.php

<?php
  if( $conn = mysqli_connect($host,$user,$senha,$banco) ){
    echo "Connection Successfull";
    } else {
    die("Problema de conexão com o Mysql ou banco de dados.");
    }
?>

Conexao_banco_close.php

<?php
  mysqli_close($conn);
?>

Script padrão para bancos de dados Mysql em linguagem PHP - VII

Biblioteca III

libCabecalhoPadrao.php

Este trecho insere um cabeçalho padrão levemente parametrizado em cada função (ação) chamada na script através de um endereço HTTP.

  <div class=h2><div class="btn b1"><?= $titulo ?> - <?= $operation ?></div></div>

  <div class=h3><div class="btn b2"><?= $description ?>&nbsp;[<?= $_SERVER['REMOTE_ADDR'] .'-' . $_SERVER['SERVER_ADDR'] ?>]

  <a class="btn" style="margin-left:50px;" href="?estilo=<?= $_GET['estilo'] ?>"><span class="btn a">TELA INICIAL</span></a>

  </div>

  </div>

Consistência de campo email com expressões regulares em PHP

A consistência dos campos de email dos formulários em linguagem HTML, de forma minimalista, pode ser muito trabalhosa se utilizarmos a famigerada função de substring.

Expressões Regulares

Para resolver o problema da forma correta, vamos utilizar as expressões regulares.

Primeira solução:

Prevê as formas que o email pode ter de forma discreta:

x@y.z, x@y.w.z, x.y@w.z ou x.y@k.w.z

A expressão regular equivalente seria:

 /^([\w]+|[\w]+\.[\w]+)@([\w]+\.[\w]+|[\w]+\.[\w]+\.[\w]+)$/

Segunda solução:

Esta é mais elegante e utiliza o princípio das máquinas finitas:

/^(\.?[\w]+){0,}@(\.?[\w]+){0,}$/

As expressões à direita e à esquerda do sinal característico "@" do formato de email são iguais, e podem ser esquematizadas da seguinte forma:

(\.?[\w]+){0,}

Os parênteses estabelecem um grupo lógico.

(\.?[\w]+){0,}

O ponto (precedido de "\" para especificar que é o caracter em si, e não uma referência simbólica da sintaxe das Expressões Regulares) e seguido do sinal de interrogação significa que ele pode ou não aparecer. Isto porque o primeiro grupo de caracteres do endereço de email não possui um ponto que o preceda.

(\.?[\w]+)

.O símbolo de qualquer letra, seguido do caracter "+" indica que o grupo lógico será uma sequência de caracteres (sem espaços).

(\.?[\w]+)

A expressão completa entre parênteses significa: Um grupo de caracteres sem espaços que pode ou não ser precedido de ponto (".").

(\.?[\w]+){0,}

O complemento {0,} indica o número de ocorrências, no caso 0 ou mais.







Script padrão para bancos de dados Mysql em linguagem PHP - VI

Biblioteca II

libScriptsJs.php

Esta biblioteca inclui o código Javascript de consistências dos campos dos diversos formulários da Engine que estamos fazendo. A função é chamada no evento OnSubmit dos formulários de Inclusão e Alteração.

    <script type="text/javascript">
      function manda(frm1){
var retorno = true;
var patt1, patt2, strdata;
var bck = "backgroundColor";
var bci = "backgroundImage";
var fCorr = "url('Corrija.png')";
var fPre = "url('Preencha.png')";
<?php
for($x=1;$x<count($arr);$x++){
 $idFld = $arr[$x][0];
 $pl = new paramLine($arr,$x,"");
 $sTipo = $pl->tipocampo;
 ?>
 // <?= $sTipo ?>
 <?php
 echo("\n");
 if( $sTipo !== "hidden" && $sTipo !== "password" ){
   switch ($sTipo){
     case "date":
?>
patt1 = /\d{1,2}[\/|\-]\d{1,2}[\/|\-]\d{4}/;
patt2 = /\d{4}[\/|\-]\d{1,2}[\/|\-]\d{1,2}/;
strdata = $("#<?= $arr[$x][0] ?>").val();
if( !( patt1.test(strdata) || patt2.test(strdata) ) ){
 alert("Formato de <?= $arr[$x][1] ?> não é o de uma data válida.");
 $("#<?= $idFld ?>").css(bck,'gold');
 $("#<?= $idFld ?>").css(bci,fCorr);
 retorno = false;
 } else {
   $("#<?= $idFld ?>").css(bck,'white');
   //$("#<?= $idFld ?>").css(bci,fPre);
 }
 //
 if( $("#<?= $idFld ?>").val() == "" ){
   alert("Campo <?= $arr[$x][1] ?> NÃO pode ser VAZIO.");
   $("#<?= $idFld ?>").css(bck,'gold');
   $("#<?= $idFld ?>").css(bci,fCorr);
   retorno = false;
   } else {
   $("#<?= $idFld ?>").css(bck,'white');
   //$("#<?= $idFld ?>").css(bci,fPre);
   }
<?php
break;
     case "select":
?>
if( $("#<?= $idFld ?>").val() == "N/A" ){
 alert("Você esqueceu de selecionar um <?= $arr[$x][1] ?> .");
 $("#<?= $idFld ?>").css(bck,'gold');
  $("#<?= $idFld ?>").css(bci,fCorr);
 retorno = false;
 } else {
   $("#<?= $idFld ?>").css(bck,'white');
   //$("#<?= $idFld ?>").css(bci,fPre);
 }
<?php
break;
     case "textarea":
if( $arr[$x][5] == "S" ){
 ?>
 if( $("#<?= $arr[$x][0] ?>").val() == "" ){
   alert("Campo <?= $arr[$x][1] ?> NÃO pode ser VAZIO.");
   $("#<?= $idFld ?>").css(bck,'gold');
   $("#<?= $idFld ?>").css(bci,fCorr);
   retorno = false;
   } else {
   $("#<?= $idFld ?>").css(bck,'white');
   //$("#<?= $idFld ?>").css(bci,fPre);
   }
 <?php
 }
break;
   
     case "email":
if( $arr[$x][5] == "S" ){
 ?>
 patt1 = /^(\.?[\w]+){0,}\@(\.?[\w]+){0,}$/;
 strdata = $("#<?= $arr[$x][0] ?>").val();
 if( $("#<?= $arr[$x][0] ?>").val() == "" ){
   alert("Campo <?= $arr[$x][1] ?> NÃO pode ser VAZIO.");
   $("#<?= $idFld ?>").css(bck,'gold');
   $("#<?= $idFld ?>").css(bci,fCorr);
   retorno = false;
   } else {
   if( !patt1.test(strdata) ){
     alert("Campo <?= $arr[$x][1] ?> não tem o formato de endereço de EMAIL.");
     $("#<?= $idFld ?>").css(bck,'gold');
     $("#<?= $idFld ?>").css(bci,fCorr);
     retorno = false;
     } else {
     $("#<?= $idFld ?>").css(bck,'white');
     //$("#<?= $idFld ?>").css(bci,fPre);
     }
   }
 <?php
 }
break;
     case "text":
if( $arr[$x][5] == "S" ){
 ?>
 if( $("#<?= $arr[$x][0] ?>").val() == "" ){
   alert("Campo <?= $arr[$x][1] ?> NÃO pode ser VAZIO.");
   $("#<?= $idFld ?>").css(bck,'gold');
   $("#<?= $idFld ?>").css(bci,fCorr);
   retorno = false;
   } else {
   $("#<?= $idFld ?>").css(bck,'white');
   // $("#<?= $idFld ?>").css(bci,fPre);
   }
 <?php
 }
break;
     case "number":
if( $arr[$x][5] == "S" ){
 ?>
 patt1 = /\d{0,<?= $arr[$x][3] ?>}/;
 patt2 = /\d{1,<?= $arr[$x][3] ?>}/;
 strdata = $("#<?= $idFld ?>").val();
 if( $("#<?= $idFld ?>").val() == "" ){
   alert("Campo <?= $arr[$x][1] ?> NÃO pode ser VAZIO.");
   $("#<?= $idFld ?>").css(bck,'gold');
   $("#<?= $idFld ?>").css(bci,fCorr);
   retorno = false;
   } else {
   $("#<?= $idFld ?>").css(bck,'white');
   // $("#<?= $idFld ?>").css(bci,fPre);
   }
 if( !( ( patt1.test(strdata) && "<?= $arr[$x][5] ?>" != "S" ) || patt2.test(strdata) ) ){
   alert("Formato de <?= $arr[$x][1] ?> não é o de um Número válido.");
   $("#<?= $idFld ?>").css(bck,'gold');
   $("#<?= $idFld ?>").css(bci,fCorr);
   retorno = false;
   } else {
   $("#<?= $idFld ?>").css(bck,'white');
   // $("#<?= $idFld ?>").css(bci,fPre);
   }
<?php
 }
break;
}
     }
   }
 ?>
return retorno;
}
    </script>

Script padrão para bancos de dados Mysql em linguagem PHP - V

Bibliotecas - I

libParamLine.php

Esta biblioteca tem duas funções que tratam essencialmente dos tipos possíveis de variáveis em uma tabela de banco de dados, não necessariamente do Mysql, mas de quase todos os bancos cujas queries sejam guiadas a SQL.

O primeiro objetivo é construir as sentenças SQL com a sintaxe correta, ou seja, colocando os conteúdos entre os delimitadores corretos, convertendo as senhas no formato criptografado e invertendo a data quando for preciso. Além disto o campo de email também é tratado.

O segundo objetivo é preparar corretamente as tags de INPUT, SELECT ou TEXTAREA, com os tipos e tamanhos corretos.

Código:

<?php
      // Classe usada para as ações: edit e editsave
      class paramLineOut{
public $delimitador;
public $valorfinal;
public $tipocampo;
public $taginput;
function __construct($arranjo,$linha,$valorparam){
 $valor = $valorparam;
 $this->valorfinal = $valorparam;
 $this->delimitador = $arranjo[$linha][7];
 $tipo = strtolower($arranjo[$linha][4]);
 $this->tipocampo = $tipo;
 $sTipo = $tipo;
 $inp = "<input";
 $this->taginput = $inp;
 switch ($tipo){
   case "select":
     $inp = "<select";
     $deli = "'";
     break;
   case "textarea":
     $inp = "<textarea";
     $deli = "'";
     break;
   case "":
     $deli = "";
     $sTipo = "number";
     break;
   case "'":
     $deli = "'";
     $sTipo = "text";
     break;
   case "email":
     $deli = "'";
     $sTipo = "text";
     break;
   case "hidden":
     $deli = "'";
     $sTipo = "hidden";
     break;
   case "pwd":
     $deli = "";
     $sTipo = "password";
     //$valor = "PASSWORD('" . $valor . "')";
     $valor = $valor;
     break;
   case "#":
     $deli = "'";
     $sTipo = "date";
     if( preg_match("/\d{1,2}[\/|\-]\d{1,2}[\/|\-]\d{4}/", $valor, $matches) ){
$dt = substr($valor,6,4) . "-" . substr($valor,3,2) . "-" . substr($valor,0,2);
//$dt = substr($valor,8,2) . "-" . substr($valor,5,2) . "-" . substr($valor,0,4);
//$dt = $valor;
} else {
$dt = $valor;
}
     
     $valor = $dt;
     break;
   default:
     $sTipo = "unknown";
     $deli = "'";
     break;
   }
   $this->delimitador = $deli;
   $this->valorfinal = $valor;
   $this->tipocampo = $sTipo;
   $this->taginput = $inp;
 }
function getDelimitador(){
 return $this->delimitador;
 }
function getValorfinal(){
 return $this->valorfinal;
 }
function getTipocampo(){
 return $this->tipocampo;
 }
}    
      // Classe usada para as ações: add, addsave e list
      class paramLine{
public $delimitador;
public $valorfinal;
public $tipocampo;
public $taginput;
function __construct($arranjo,$linha,$valorparam){
 $valor = $valorparam;
 $this->valorfinal = $valorparam;
 $this->delimitador = $arranjo[$linha][7];
 $tipo = strtolower($arranjo[$linha][4]);
 $this->tipocampo = $tipo;
 $sTipo = $tipo;
 $inp = "<input";
 $this->taginput = $inp;
 switch ($tipo){
   case "select":
     $inp = "<select";
     $deli = "'";
     break;
   case "textarea":
     $inp = "<textarea";
     $deli = "'";
     break;
   case "":
     $deli = "";
     $sTipo = "number";
     break;
   case "'":
     $deli = "'";
     $sTipo = "text";
     break;
   case "email":
     $deli = "'";
     break;
   case "hidden":
     $deli = "'";
     $sTipo = "hidden";
     break;
   case "pwd":
     $deli = "";
     $sTipo = "password";
     $valor = "PASSWORD('" . $valor . "')";
     break;
   case "#":
     $deli = "'";
     $sTipo = "date";
     if( preg_match("/\d{1,2}[\/|\-]\d{1,2}[\/|\-]\d{4}/", $valor, $matches) ){
$dt = substr($valor,6,4) . "-" . substr($valor,3,2) . "-" . substr($valor,0,2);
} else {
$dt = $valor;
}
     $valor = $dt;
     break;
   default:
     $sTipo = "unknown";
     $deli = "'";
     break;
   }
   $this->delimitador = $deli;
   $this->valorfinal = $valor;
   $this->tipocampo = $sTipo;
   $this->taginput = $inp;
 }
function getDelimitador(){
 return $this->delimitador;
 }
function getValorfinal(){
 return $this->valorfinal;
 }
function getTipocampo(){
 return $this->tipocampo;
 }
}
function openQuadro(){
 echo "<br><center><div class=moldb><div class=lin><div class=mold><br>";
 }
function closeQuadro(){
 echo "</div></div></div></center>";
 }
?>


terça-feira, 18 de junho de 2013

Script padrão para bancos de dados Mysql em linguagem PHP - IV

Estrutura da engine genérica

Vamos colocar esquematicamente os includes em relação ao diagrama anterior:


Includes e requires

O Include contém um trecho reaproveitável de código PHP. Já o Require contém um código reaproveitável de HTML. No entanto, devido à sua característica de macrosubstituição, o Require pode conter um trecho em PHP. Além desta característica reside a verdadeira DIFERENÇA: se houver erro num include, e execução prossegue, ao contrário do que acontece num Require. Como Require lembra REQUERIDO, é claro que a script tem que obrigatoriamente abortar caso o trecho não seja encontrado.

No entanto, neste padrão não fomos ortodoxos, mas você pode sê-lo.

Include/Require  Finalidade 
ExemploDefinicao.inc Contém o esquema dos campos a serem preenchidos e apresentados
pelas ações da script 
libParamLine.php Contém uma biblioteca de funções de tratamento de tipos e delimitadores para os conteúdos dos campos a serem preenchidos.
libScriptsJs.php Armazena as funções Javascript 
libCabecalhoPadrao.php Contém um trecho em HTML com o cabeçalho padrão das várias ações da
script. 
Conexao_banco.php  Executa a abertura da tabela no banco de dados e coloca o pointer em $conn 
Conexao_banco_close.php   Fecha a conexão do banco ($conn). 

Nos próximos posts vamos detalhar os 5 últimos includes (o primeiro já o foi).






segunda-feira, 17 de junho de 2013

Script padrão para bancos de dados Mysql em linguagem PHP - III

Vamos conceber uma script genérica (engine) que vai ler a estrutura de uma tabela Mysql a partir de um arranjo em PHP. Não vamos nos lançar na trabalhosa e fútil busca pelo genérico do genérico, fazendo mirabolâncias para ler as tabelas internas do Mysql, até porque pretendemos fazer "views", e não um phpmyadmin.

Ações da script

A script em PHP vai tomar conhecimento de qual ação ela precisa fazer através de um parâmetro na URL de chamada através do protocolo http. O parâmetro que vamos convencionar é action, e as possibilidades dele são:

 action Descrição da funcionalidade 
add Procedimento de inclusão. Mostra um formulário para acréscimo de registros à tabela. 
addsave Procedimento de salvamento do registro que veio da ação add.
edit Procedimento de edição. Mostra um formulário para alteração do registro. A ação deve ter o acréscimo do parâmetro Id (AutoNumeração), contendo o número do registro. 
editsave Procedimento de salvamento do registro que veio da ação edit.
dele Procedimento de preparo do registro para deleção. 
delesave  Procedimento de confirmação da deleção do registro. 
list Mostra uma relação dos registros a partir de um parâmetro e de um conteúdo escolhido.

Organização das ações

As ações estão implementadas dentro da engine na forma do comando switch(){ case ... }.

Diagrama das ações


Em bom código PHP, teríamos, a grosso modo, o seguinte:

// O ajuste da variável $action é feito no include que possui os parâmetros (ExemploDefinicao.php)
$action = strtolower($_REQUEST['action']);
switch($action){
case "add":
.
.
.
break;
case "addsave":
.
.
.
break;
case "edit":
.
.
.
break;
case "editsave":
.
.
.
break;
case "dele":
.
.
.
break;
case "delesave":
.
.
.
break;
case "list":
.
.
.
break;
default:
.
.
.
}

No próximo post começaremos a detalhar os demais includes, para depois especificar cada ação.







Script padrão para bancos de dados Mysql em linguagem PHP - II

No post anterior mostramos o coração das scripts de controle de registros em tabelas de bancos de dados Mysql (ou qualquer outro banco) para a linguagem PHP.

Mas o núcleo destas scripts precisa ter outros parâmetros para fácil configuração em um pedaço de código que seja passível de manutenção por até um estagiário. A seguir mostramos este include completo, ao qual demos o nome de ExemploDefinicao.inc:

<?php
// Mensagens
$msgAdd = "<p>Registro INCLU͍DO.<br>Obrigado. Fim da operação.</p>";
$msgEdit = "<p>Registro ALTERADO.<br>Obrigado. Fim da operação.</p>";
$msgDel = "<p>Registro EXCLU͍DO.<br>Obrigado. Fim da operação.</p>";
// Tí­tulos
$titulo = "Controle Padrão de Registros de Tabela em Banco de Dados";
$operAdd = "INCLUSÃO";
$descAdd = "Prepara a inclusão de um Registro";
$operAddSave = "INCLUSÃO - Gravação";
$descAddSave = "Efetua a inclusão definitiva do Registro";
$operEdit = "ALTERAÇÃO";
$descEdit = "Manutenção em um Registro";
$operEditSave = "EDIÇÃO - Gravação";
$descEditSave = "Efetivação da Manutenção no Registro";
$operDel = "DELEÇÃO";
$descDel = "Deleção de um Registro";
$operDelSave = "Deleção - Gravação";
$descDelSave = "Remoção definitiva do Registro";
$operList = "Relação dos Registros";
$descList = "Painel de Controle dos Registros";
// Botões Submit
$btnAdd = "GRAVAR";
$btnEdit = "ATUALIZAR";
$btnDel = "Confirmar DELEÇÃO";
// Permissões para as operações
$permiteAdd = TRUE;
$permiteEdit = TRUE;
$permiteDel = TRUE;
$permitePesq = TRUE;
$action = strtolower($_REQUEST['action']);
// Parâmetros de acesso ao Banco de Dados
$host = "localhost";
$user = "guest"; $senha = "xxxxxx";
$banco = "banco"; $tabela = "Tabela1";
// Arranjo de configuração do SCHEMA
$arr = array(
  "0"=> array("Id","Id",6,6,"","S", NULL,"NÃO preencha",""),
  "1"=> array("Descri","Descrição",25,50,"textarea","S",NULL,"",""),
  "2"=> array("DtAtiv","Data da Ativação",10,10,"#","S", NULL, "", ""),
  "3"=> array("TpReg","Tipo do Registro",10,10,"select","N","<option value=N/A>Nenhum<option value=A>A<option value=B>B<option value=C>C","",""),
  "4"=> array("Senha","Senha",10,10,"pwd","N",NULL,"Misture letras e números",""),
  "5"=> array("Cod","Codificação",25,25,"'","N",NULL,"","utf-8"),
  "6"=> array("Email","Email",50,80,"email","S",NULL,"",""),
  "7"=> array("NoPedido","No.do Pedido",4,4,"","N",NULL,"","")
  );
$NoCampos = count($arr);
?>

Este include se torna um arquivo de configuração da script genérica (engine) que faremos a seguir. Se o cliente para o qual estamos prestando serviço pedir modificações cosméticas na aparência dos formulários e partes funcionais da página PHP, quase todas elas residem neste include.

No próximo post mostraremos a estrutura geral da script genérica para manipulação das informações de uma tabela de dados do Mysql, utilizando este include.


Script padrão para bancos de dados Mysql em linguagem PHP - I

Vamos iniciar aqui um curso completo para explicar o acesso ao banco de dados Mysql através de scripts PHP, com os procedimentos para Inclusão, Alteração, Deleção e Relação de registros.

Esta script será genérica, ou seja, construindo um arranjo de forma apropriada, poderemos ter o controle destas quatro operações citadas sobre a estrutura de qualquer tabela do Mysql.

O arranjo mestre da estrutura

Este arranjo é uma espécie de derivado dos SCHEMAs de bancos de dados:

Tabela 1
 Índice Finalidade 
 0  Nome do campo no Mysql
 1  Nome do campo para exibição no formulário 
 2  Tamanho do campo no formulário (em caracteres)
 3  Tamanho máximo do conteúdo no campo do formulário (em caracteres)
 4  Tipo do campo (Ver a próxima tabela)
 5  Obrigatoriedade do preenchimento ("S" ou "N")
 6  Usado para o conteúdo de um campo do tipo Select. Se não for, deve conter NULL
 7  Mensagem auxiliar de preenchimento que aparecerá à frente do campo no formulário
 8  Valor default que vai aparecer no formulário de Inclusão

Tabela 2
 Tipo Descrição do conteúdo 
 "'"  (Aspas simples) Tipo texto em geral
 ""  (Vazio) Tipo numérico
# Campo data. A entrada pode ser no formato ano/mes/dia ou dia/mes/ano
email Campo de email
pwd Campo de senha
select Campo com um número finito e estático de opções
textarea Campo cujo conteúdo é do tipo a ser armazenado em um campo MEMO ou BLOB ou
VARCHAR de tamanho acima de 80 caracteres.

O include do SCHEMA

O preenchimento de um arranjo exemplo no include é:

$arr = array(
  "0"=> array("Id","Id",6,6,"","S", NULL,"NÃO preencha",""),
  "1"=> array("Descri","Descrição",25,50,"textarea","S",NULL,"",""),
  "2"=> array("DtAtiv","Data da Ativação",10,10,"#","S", NULL, "", ""),
  "3"=> array("TpReg","Tipo do Registro",10,10,"select","N","<option value=N/A>Nenhum<option value=A>A<option value=B>B<option value=C>C","",""),
  "4"=> array("Senha","Senha",10,10,"pwd","N",NULL,"Misture letras e números",""),
  "5"=> array("Cod","Codificação",25,25,"'","N",NULL,"","utf-8"),
  "6"=> array("Email","Email",50,80,"email","S",NULL,"",""),
  "7"=> array("NoPedido","No.do Pedido",4,4,"","N",NULL,"","")
  );
$NoCampos = count($arr);

A variável $NoCampos facilita o trabalho na hora de estabelecer os loops de exibição dos campos.

Repare nos tipos dos campos aparecendo após os dois tamanhos de campo. Somente o campo 5 tem um valor default. O campo do tipo select tem a lista de opções após o local para especificação de obrigatório ou não.

Devido à sua flexibilidade, os arranjos em PHP permitem uma manipulação bem mais simples que os arranjos em VBscript no ASP.

No próximo post veremos a estrutura completa do include com o SCHEMA.

sábado, 15 de junho de 2013

Teclado ABNT2 no Kubuntu 12.04, 12.10 e 13.04

Periféricos são uma dor de cabeça para se configurar. Mexer à mão em arquivos .conf é uma chateação.

Graças a Deus existem comandos que salvam a vida do analista e do programador. Se o seu teclado é do tipo ABNT2, e o sistema oferece a língua portuguesa, e as teclas de acento não funcionam, digite o seguinte comando no console:

setxkbmap -model abnt2 -layout br

Isto equivale a editar os arquivos de configuração do X11 (/etc/X11/xorg.conf, seção InputDevice). Editar arquivos de configuração à mão é muito bom para se jactar de ter conhecimento, mas já passamos deste tempo. Tudo tem que ser dirigido por aplicações gráficas.

Estranho é a opção de ABNT2 não estar já disponível no Configurador do Kubuntu.

Bom proveito.

quinta-feira, 13 de junho de 2013

Erro 0xc0000225 na instalação do Windows 2008 Server x64

No árduo trabalho de escolha e teste de servidores, tanto para a Web como para Redes e Intranets, e de virtualização dos mesmos, tivemos a oportunidade de proceder à instalação do Windows 2008 Server R2 em 64 bits.

Situação Inicial

A máquina (Dual Core) já possuía instalados o Windows Seven e o Linux Kubuntu 13.04, com todos os periféricos já instalados, inclusive um Wifi USB ASUS.

Por que uma situação tão complexa ? Para provar a capacidade do 2008 R2 de reconhecer sistemas instalados e incorporá-los ao seu menu de boot. Pois bem, a instalação parou com o erro 0xc0000225. Tentamos continuar, mas o erro reapareceu.

Os problemas

Então demos o boot para ver se tudo o mais continuava funcionando. E para nosso desprazer, nem Windows e nem Linux. O 2008 corrompeu a tabela do grub do Linux. Nem o Windows 7 ofereceu mais a opção de reparar.

É decepcionante que o 2008 não ofereça possibilidades de recuperação, e pelo que apuramos das causas, o que falta é a Microsoft dar um mínimo de recomendações. Além disto, com o domínio de sistemas e hardware que vem de pelo menos uns 30 anos, a Microsoft DEVERIA reconhecer na tabela de partições os sistemas do tipo Linux, e apresentá-los em seu menu de boot. Lamentável.

Solução

Basta HABILITAR o IO/APIC na BIOS, bem como a tecnologia Hyper-V, e os sistemas de 64 bits poderão ser instalados sem problema. Uma coisa tão simples que a Microsoft poderia colocar em letras vermelhas na capa da mídia do Windows 2008. É muita omissão.

Comentários

A Microsoft, como pretensa líder de vendas em softwares e soluções para servidores precisa, o quanto antes, colocar duas funcionalidades em seus produtos:

Detector de partições, inclusive Linux;
Opções para reparo de partições, bem como seu redimensionamento EM TEMPO DE INSTALAÇÃO;

Durante a instalação do Linux, é provida uma interface gráfica para redimensionamento, exclusão e criação de partições, bem como o GRUB, que possibilita configurar o comportamento dos diversos sistemas operacionais disponíveis em uma máquina.


sexta-feira, 7 de junho de 2013

Kubuntu - Configuração do Sistema (System Settings) não consegue trocar o Locale (línguagem do sistema)

Entre num terminal (CTRL-ALT-F1 ou CTRL-ALT-Fn) e execute o comando:

dpkg --configure -a

O diálogo de autenticação para Locale passará a aparecer.

Este problema está relacionado ao não funcionamento do Muon (Gerenciador de pacotes). Tudo o que exigir autenticação do sistema não vai funcionar. Este comando conserta o problema.