Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Boa noite!
Acabei de criar a classe que faz toda gestão dos dados enviados via $_POST. O tratamento é feito com AJAX e gostaria de saber a opinião de vocês quando a melhorias no código. Eu fazia manualmente um a um e durante algumas semanas fiquei pensando em como automatizar todo esse processo. Ainda estou aprendendo e tenho me esforçado ao máximo pra poder entender todo o conceito do POO. Sei que é muita coisa mas um dia chego lá. Então lá vai
<?php
/**
* UpdateData.class [ Helper ]
* Responsável por verificar os dados enviado via $_POST e inserir ou atualizar essas informações
* no banco de dados
*
*/
class UpdateData {
/** A data e hora atual */
private $DataCadastro;
/** A tabela que receberá a ação */
private $Table;
/** Os campos que serão validados e salvos na tabela */
private $Fields;
/** Os dados que serão utilizados para realizar a ação na tabela */
private $DataObj;
/** A mensagem de erro */
private $Errors;
/** A mensagem de sucesso */
private $Success;
/** Itens para checar se o registro já existe */
private $Itens;
/** Construct */
function __construct($Table, array $Fields, $Itens = null) {
$this->Table = $Table;
$this->Fields = $Fields;
$this->Itens = $Itens;
$this->DataCadastro = date('Y-m-d H:i:s');
// Execute methods
$this->CheckFields();
$this->SetAction();
}
/**
* <b>CheckFields: </b> Método responsável por verificar se o campo está vazio e retornar a mensagem
* de erro em formato de json
*
* @return json
*/
public function CheckFields(){
if(is_array($this->Fields)):
/** Define os dados que serão utilizados para manipular a tabela */
$this->DataObj = $this->Fields;
/** Trata alguns campos removendo caracteres da máscara jQuery */
foreach($this->DataObj as $IndiceObj):
if($IndiceObj=='cnpj' || $IndiceObj=='cpf' || $IndiceObj=='cep' || $IndiceObj=='telefone'):
$this->DataObj = str_replace(['_', '-', '.', '/'], '', $this->DataObj);
endif;
endforeach;
/** Passwords => For change | Encoding sha1() */
if(isset($this->Fields['senha']) && !empty($this->Fields['senha'])):
foreach($this->Fields as $Indice => $Val):
if($Indice == 'senha'):
$this->Fields['senha'] = sha1($this->Fields['senha']);
endif;
endforeach;
endif;
/** Passwords => For check if it's correctly */
if(isset($this->Fields['atual_pass']) && !empty($this->Fields['atual_pass'])):
foreach($this->Fields as $Indice => $Val):
if($Indice == 'atual_pass'):
$this->Fields['atual_pass'] = sha1($this->Fields['atual_pass']);
endif;
endforeach;
$ReadPass = new Read;
$ReadPass->ExeRead('rio_clientes', 'senha,id,email', 'WHERE senha = :senha_atual', "senha_atual={$this->Fields['atual_pass']}");
if(!$ReadPass->getResult() && empty($this->Success)):
$this->Errors=['erros' => "A senha atual está incorreta#exibir_erros"];
echo json_encode($this->Errors);
exit;
endif;
endif;
/** Validação para tela de alteração de dados */
if($this->CheckAction()==1):
$this->Errors=['erros' => "Preencha ou o campo com o novo e-mail ou o campo com a nova senha. E informe a senha atual para concluir.#exibir_erros"];
echo json_encode($this->Errors);
exit;
elseif($this->CheckAction()==2):
$this->Errors=['erros' => "Tudo certo. Basta informar sua senha atual.#exibir_erros"];
echo json_encode($this->Errors);
exit;
elseif($this->DataObj['action']!='validate_data_access'):
/** Faz a validação dos campos */
foreach($this->Fields as $Indice => $Val):
if($Indice != 'action' && $Indice != 'id' && empty($Val)):
$this->Errors=['erros' => "Campo obrigatório#{$Indice}"];
echo json_encode($this->Errors);
exit;
endif;
endforeach;
endif;
endif;
}
/** PRIVATES METHODS */
/**
* <b>CheckDuplicidade: </b> Método responsável por verificar se o registro já existe na tabela
*
* @return boolean
*/
private function CheckDuplicidade() {
if(!empty($this->Itens) && !empty($this->Fields[$this->Itens])):
$ReadItens = new Read;
$ReadItens->ExeRead($this->Table, $this->Itens, "WHERE {$this->Itens} = :itens AND id != :id", "itens={$this->Fields[$this->Itens]}&id={$this->Fields['id']}");
if($ReadItens->getResult()):
return false;
else:
return true;
endif;
else:
return true;
endif;
}
/**
*
*/
private function CheckAction() {
if($this->DataObj['action']=='validate_data_access'):
if(empty($this->DataObj['email']) && empty($this->DataObj['senha'])):
return 1;
elseif(!empty($this->DataObj['email']) && empty($this->DataObj['senha']) && empty($this->DataObj['atual_pass'])):
return 2;
elseif(empty($this->DataObj['email']) && !empty($this->DataObj['senha']) && empty($this->DataObj['atual_pass'])):
return 2;
endif;
endif;
}
/**
* <b>SetAction: </b> Método privado responsável por realizar a ação na tabela
*
* @return boolean
*/
private function SetAction() {
/** Remove alguns índices do array, por padrão todos os campos que não estão na tabela */
unset($this->DataObj['id']);
unset($this->DataObj['action']);
unset($this->DataObj['atual_pass']);
// Elimina o e-mail do update, se ele estiver vazio
if(empty($this->DataObj['email'])):
unset($this->DataObj['email']);
endif;
// Elimina a senha do update, se ela estiver vazia
if(empty($this->DataObj['senha'])):
unset($this->DataObj['senha']);
endif;
// Realiza o insert
if(!isset($this->Fields['id']) || empty($this->Fields['id'])):
if($this->CheckDuplicidade()===true):
$InsertData = new Create;
$InsertData->ExeCreate($this->Table, $this->DataObj);
if($InsertData->getResult()):
$this->Success=['sucesso' => "Registro inserido com sucesso#sucesso"];
echo json_encode($this->Success);
endif;
else:
$this->Errors=['erros' => "Esse registro já existe. Não será possível realizar essa ação com essa informações.#exibir_erros"];
echo json_encode($this->Errors);
exit;
endif;
// Realiza o update
else:
if($this->CheckDuplicidade()===true):
// Salva a data de alteração da senha
if(!empty($this->DataObj['senha'])):
$this->DataObj['data_alteracao_senha'] = $this->DataCadastro;
endif;
// Realiza o update
$UpdateData = new Update;
$UpdateData->ExeUpdate($this->Table,$this->DataObj, "WHERE id=:id", "id={$this->Fields['id']}");
// Atualiza a sessão com o novo e-mail
if(!empty($this->DataObj['email'])):
$sessao = new Session;
$_SESSION['logado'] = $this->DataObj['email'];
endif;
// Mensagem de sucesso
if($UpdateData->getResult()):
$this->Success=['sucesso' => "Dados atualizados com sucesso#sucesso"];
echo json_encode($this->Success);
endif;
else:
$this->Errors=['erros' => "Esse registro já existe. Não será possível realizar essa ação com essa informações.#exibir_erros"];
echo json_encode($this->Errors);
exit;
endif;
endif;
}
}
Usage
/** Post form */
$Post=filter_input_array(INPUT_POST);
/** Define as variáveis utilizadas pela classe */
switch($Post['action']):
// Meus dados
case "validate_meus_dados":
$Table = 'clientes';
$Iten = ''; // Quando existir, irá verificar se o registro é duplicado ou não
break;
endswitch;
/** Objeto da classe */
$updData=new UpdateData($Table, $Post, $Iten);
Acredito que o que você tem é um bom ponto de partida para uma boa aprendizagem.
Você colocou uma classe, eu vou colocar dicas para você melhorar sua classe e experiência na POO. Em um primeiro momento, vou questionar sua "codificação". Conforme for o andamento, irei questionar outros detalhes da classe.
Comentários:
Tais como:
/**
* @var \DateTime
**/
private $DataCadastro;
Nomemclatura:
Eu vejo dois problemas, ambos são pontos de vista mas vão interferir no seu código
- UpperCamelCase para nomes de classes, interfaces, traits e namespaces;
- LowerCamelCase para métodos, funções, atributos e variáveis.
Veja:
private function FriendUrlModelo() {
private function TrataMask() {
private function CreateItensParseToCompare() {
private function PassAtualCheck() {
Todos os métodos, acima listados, possuem palavras em mais de um idioma. Isso é ruim para a leitura e entendimento do código.
Você usando dois idiomas, eu tenho que adivinhar o significado do nome da classe:
class UpdateData {
Você está atualizando uma data ou dados? Quando eu ler a classe, vou entender o funcionamento da classe e o significado do nome, mas isso por si só é ruim. Eu não deveria conhecer a classe para entender o que a classe se propõe.
Preceitos e conceitos:
Veja o phpDoc abaixo:
@return json $erros Caso a senha esteja incorreta
Não retorne o json, lance uma exception e, então, o seu cliente deve tratar a alteração do fluxo de execução. Sua classe não deve ser responsável pelo ouput, ao menos não deveria.
$this->DataCadastro = date('Y-m-d H:i:s');
Você está usando uma string literal, seria mais interessante um objeto:
$this->DataCadastro = new \DateTime();
Complexidade ciclomática alta:
Eu não realizei os testes, mas sei que a complexidade do seu código é alta, ele possui muitas variações no fluxo de execução. E isso deve ser tratado. Para realizar o tratamento, eu recomendo a leitura sobre Object Calisthenics, isso veio do java mas agregou muito ao PHP, poderá ler nos links abaixo:
http://pt.slideshare.net/guilhermeblanco/php-para-adultos-clean-code-e-object-calisthenics
Leituras adicionais:
PSRs: Não é obrigatório o uso de tudo que é dito, nem eu mesmo utilizo tudo, mas é importante conhecer, entender e saber aplicar.
Uma vez que são regras desenvolvidas pela e para a comunidade PHP.
PSR - 1: http://www.php-fig.org/psr/psr-1/
PSR - 2: http://www.php-fig.org/psr/psr-2/
PSR - 4: http://www.php-fig.org/psr/psr-4/
Ferramentas sugeridas (para o linux nesse caso):
PHP Mess Detector: Essa "belezura" lhe mostra várias "bagunças" que podem haver no seu código, além de alta complexidade e alguns detalhes a mais.
PHP CodeSniffer: Lhe aponta questões definidas nas PSRs e alguns pontos a mais de codificação. Os mesmos pontos ressaltados pela PSR vale aqui, é bom saber, mas não precisa utilizar tudo a risca.
Adorei a avaliação Gabriel Heming. Já estou trabalhando nessas melhorias. Agora ficou uma dúvida, que ainda não testei mas, acredito que vai dar bizu. Se ao invés de retornar os erros e sim os Exceptions, que realmente, melhorou muito a legibilidade do código, como faço para jogá-lo para o json.
Porque essa validação trabalha em conjunto com o AJAX, certo ?! Eu envio os dados para a classe e, no caso como está acima, ele retorna a mensagem de erro no formato json pra que eu possa exibí-la ao usuário. É possível que eu faça esse tratamento diretamente no catch e retornar o json corretamente ?
Sim, você deve tratar diretamente no try/catch e retornar o json, mas o mais importante é aonde ficará esse try/catch.
Quando você desenvolve uma biblioteca, deve separar o que é a biblioteca e quem está usando.
Se um dia você quiser usar sua biblioteca para updates síncronos, que seria a requisição normal do servidor, sua biblioteca estaria "amarrada" ao fato de sempre retornar um json, ou executar um exit ou realizar o output (print/echo) de informação.
A responsabilidade de saída/output deve ser realizada pelo cliente que está utilizando a biblioteca. Mas cada um com sua responsabilidade, uma model não pode sair printando informação por ai... :lol:
Mas caso a Model que esteja utilizando sua biblioteca receba um try/catch, ela pode tomar para si a responsabilidade de tratar a exceção ou repassar o tratamento (reenviando a exception ou criando uma nova exception) para o controller e, então, o controller pode ter a responsabilidade de enviar a informação para o navegador.
Aqui fica um pouco contraditório, visto que nenhuma view deveria ser exibida (visto do ponto de vista que é um retorno para o navegador). Entretanto, para a infomação chegar ao navegador, deve ser printado. Nesse caso, eu não vejo problema em possuir na camada de controle um echo json_encode, visto que é um tipo de retorno que é realizado em forma de output.
Legal Gabriel, o interessante da Orientação a Objetos é que a teoria faz muita diferença na hora do aprendizado. Fiz algumas modificações nos comentários, tentei padronizar com o phpDoc, mas confesso que sou fraco em comentários e tratamento de erros, estou inclusive estudando sobre o assunto pra resolver isso de uma vez =p
Eu vou testar agora porque provavelmente travou em alguma coisa, mas já não me importa que funcione e sim que eu saiba o que estou fazendo. Porque se eu sei o que fiz sei identificar o problema :v
Mas se quiser me ajudar pode apontar possíveis pontos para melhorá-la ainda mais.
Tentei diminuir a complexidade ciclomática, bem legal os artigos.
<?php
ini_set('display_errors',0);
ini_set('display_startup_erros',0);
/**
* <b>ChangeMySQLTableRows.class [ Change Rows Table ]: </b>
* Altera uma ou mais linhas da tabela MySQL definida na variável private $Table
* Os comandos podem ser tanto
*
* @copyright (c) 2015, Samuel dos Santos Programação Criativa
*/ private $DataCadastro;
/** @var Table The table where the data are change */
private $Table;
/** @array Fields Container for params coming from $_POST form */
private $Fields;
/** @array DataObj Container for @array Fields */
private $DataObj;
/** @var Erros The error message */
private $Errors;
/** @var Success The success message */
private $Success;
/** @array Itens To check if the record is duplicated before inserting it */
private $Itens;
/** @var Pase To create a bind values for @var Itens */
private $Parse;
/**
* @__contruct Required @var Table what receive changes,
* @array Fields what it contains all $_POST itens from form,
* @array Itens Optional if you want to compare fields existings report it in forma ['item' => $Post['field']]
*
*/
function __construct($Table, array $Fields, $Itens = null) {
$this->Table = $Table;
$this->Fields = $Fields;
$this->Itens = $Itens;
$this->DataCadastro = new \DateTime();
$this->DataObj = $this->Fields;
// Execute methods
$this->verifyFields();
$this->setActions();
}
/************************************************************
* ********************** Private methods **********************/
/**
* <b>verifyFields: </b> Verify all fields and all messages
*
* @return json
*/
private function verifyFields(){
if(is_array($this->Fields)):
/** @method friendUrlModelProduct() */
$this->friendUrlModelProduct();
/** @method RemoveMask() */
$this->removeMask();
/** @method encodingSha1() */
$this->encodingSha1();
/** @method checkPassActual() */
$this->checkPassActual();
/** @method setErros() */
$this->setErros();
endif;
}
/**
* <b>setErros: </b> Set the errors and return from JSON
*
* @return Exception
*/
private function setErros() {
// Validação para tela de alteração de dados
if($this->DataObj['action']!='validate_data_access'):
// Faz a validação dos campos fora da tela de alteração de dados
foreach($this->Fields as $Indice => $Val):
// Lançamos os campos com exceções, ou seja, com preenchimento opcional
if($Indice != 'action' && $Indice != 'id' && empty($Val) && $Indice != 'garantia' && $Indice != 'link' && $Indice != 'id_sub1' && $Indice != 'id_sub2' && $Indice != 'id_sub3'):
$this->Errors=['erros' => "Campo obrigatório#{$Indice}"];
echo json_encode($this->Errors);
exit;
endif;
endforeach;
endif;
}
/**
* <b>createBindValues: </b> Create bindValues in format :bind | =value to check that the record alread exists in $var Table
* on this method @checkAlreadyExists
*
* @return array Return the bindValues for the query
*/
private function createBindValues() {
foreach($this->Itens as $Itens => $Val):
$this->Itens .= $Itens . ' =:' . $Itens . ' AND ';
$this->Parse .= $Itens . '=' . $Val . '&';
endforeach;
$this->Itens = substr($this->Itens, 0, strrpos($this->Itens, 'AND'));
$this->Parse = substr($this->Parse, 0, strrpos($this->Parse, '&'));
$this->Itens = str_replace('Array', '', $this->Itens);
}
/**
* <b>checkAlreadyExists: </b> Compare the @array Iten[key] whith @var Iten[val]
* If match it that mean the row already exists in the @var Table so the method stop and return throw new Exception
*
* @return Exception in case of error or booleano
*/
private function checkAlreadyExists() {
if(!empty($this->Itens)):
/** Set id = 0 when this not isset and make the query works correctly */
if(!isset($this->DataObj['id'])):
$this->DataObj['id'] = 0;
endif;
/** @method createBindValues()*/
$this->createBindValues();
/** @class composer */
try {
$ReadItens = new Read;
$ReadItens->ExeRead($this->Table, '*', "WHERE {$this->Itens} AND id != :id", $this->Parse . "&id={$this->DataObj['id']}");
if($ReadItens->getResult()):
throw new Exception("Esse registro já existe.", E_USER_NOTICE);
endif;
} catch (Exception $e) {
echo $e;
}
else:
return true;
endif;
}
/**
* <b>changeDataUser: </b> Check for content in a input
* Try if all this is null if not, try if either is empty and return the message error
*
* @return Exception
*/
private function changeDataUser() {
if($this->DataObj['action']=='validate_data_access'):
if(empty($this->DataObj['email']) && empty($this->DataObj['senha'])):
$e = new Exception('Preencha ou o campo com o novo e-mail ou o campo com a nova senha. E informe a senha atual para concluir.', E_USER_NOTICE);
elseif(!empty($this->DataObj['email']) && empty($this->DataObj['senha']) && empty($this->DataObj['atual_pass'])):
$e = new Exception('Tudo certo. Basta informar sua senha atual.', E_USER_NOTICE);
elseif(empty($this->DataObj['email']) && !empty($this->DataObj['senha']) && empty($this->DataObj['atual_pass'])):
$e = new Exception('Tudo certo. Basta informar sua senha atual.', E_USER_NOTICE);
endif;
endif;
}
/**
* <b>fFriendUrlModelProduct: </b> Transforms the product model to work with url's friendly
*
* @return array Increment the @array DataObj with a new index
*/
private function friendUrlModelProduct() {
if(isset($this->DataObj['modelo']) && !empty($this->DataObj['modelo'])):
$Funcoes=new Valid;
$this->DataObj['modelo_tratado'] = $Funcoes->retira_acentos(utf8_decode($this->DataObj['modelo']), '-');
endif;
}
/**
* <b>removeMask: </b> Remove the characters aditionais from maks plugin jQuery
*
* @return array All set fields without the characters from mask
*/
private function removeMask() {
if(isset($this->DataObj['preco']) && !empty($this->DataObj['preco'])):
$this->DataObj['preco'] = str_replace('.', '', $this->DataObj['preco']);
$this->DataObj['preco'] = str_replace(',', '.', $this->DataObj['preco']);
endif;
foreach($this->DataObj as $IndiceObj):
if($IndiceObj=='cnpj' || $IndiceObj=='cpf' || $IndiceObj=='cep' || $IndiceObj=='telefone'):
$this->DataObj = str_replace(['_', '-', '.', '/'], '', $this->DataObj);
endif;
endforeach;
}
/**
* <b>encodingSha1</b> Encoding password fields with sha1
*
* @return array Change field passwords value in @array DataObj with value encoding by sha1
*/
private function encodingSha1() {
if(isset($this->DataObj['senha']) && !empty($this->DataObj['senha'])):
$this->DataObj['senha'] = sha1($this->DataObj['senha']);
endif;
}
/**
* <b>checkPassActual:</b> Check if this actual password value is true
*
* @return json $erros Caso a senha esteja incorreta
*/
private function checkPassActual() {
if(isset($this->DataObj['atual_pass']) && !empty($this->DataObj['atual_pass'])):
/** @return Encoding actual password by sha1 */
$this->DataObj['atual_pass'] = sha1($this->DataObj['atual_pass']);
try{
/** @class composer */
$ReadPass = new Read;
$ReadPass->ExeRead('rio_clientes', 'senha,id,email', 'WHERE senha = :senha_atual', "senha_atual={$this->DataObj['atual_pass']}");
if(!$ReadPass->getResult() && empty($this->Success)):
throw new Exception('A senha atual está incorreta', E_USER_NOTICE);
endif;
} catch (Exception $e) {
echo $e;
}
endif;
}
/**
* <b>unsetFields: </b> Unset index from @array Dataobj with a specif rules
*
* @return array @array DataObj with removeds indexes
*/
private function unsetFields() {
/** @return Remove the index from @array DataObj */
unset($this->DataObj['id']);
unset($this->DataObj['action']);
unset($this->DataObj['atual_pass']);
/** @return Remove the index email from @array DataObj if is null */
if(empty($this->DataObj['email'])):
unset($this->DataObj['email']);
endif;
/** @return Remove the index senha from @array DataObj if is null */
if(empty($this->DataObj['senha'])):
unset($this->DataObj['senha']);
endif;
}
/**
* <b>setActions: </b> Execute the principals methods
* Can be a insert or a update in a @var Table
*
* @return Exception Container a message success
*/
private function setActions() {
/** @method unset unsetFields() Remove indexes from @array DataObj */
$this->unsetFields();
/** @method Insert insertNewRow() Insert a new record in a @var Table */
if(!isset($this->Fields['id']) || empty($this->Fields['id'])):
$this->insertNewRow();
/** @method Update updateNewRow() Update a new record in a @var Table */
else:
$this->updateNewRow();
endif;
}
/**
* <b>setNotExistsFields: </b> Create a new indexes in a @array DataObj
*
* @return array @array DataObj with the new indexes
*/
private function setNotExistsFields() {
if(!empty($this->DataObj['senha'])):
$this->DataObj['data_alteracao_senha'] = $this->DataCadastro;
endif;
}
/**
* <b>updateSession: </b> Update index session when e-mail is update in a @var Table
*
* @return array New email value for currenctly session
*/
private function updateSession() {
if(!empty($this->DataObj['email'])):
/** @class composer */
$sessao = new Session;
/** @return array New value for set index $_SESSION */
$_SESSION['logado'] = $this->DataObj['email'];
endif;
}
/**
* <b>insertNewRow: </b> Insert a new row in a @var Table
*
* @return boolean
*/
private function insertNewRow() {
if($this->checkAlreadyExists()):
try {
$InsertData = new Create;
$InsertData->ExeCreate($this->Table, $this->DataObj);
/** @return Exception Message successful */
if($InsertData->getResult()):
endif;
} catch (Exception $e) {
/** @return json Message in json format for AJAX */
}
endif;
}
/**
* <b>updateNewRow: Update a exists row in a @var Table</b>
*
* @return boolean
*/
private function updateNewRow() {
if($this->checkAlreadyExists()):
/** @methos Create setNotExistsFields() Create new indexes in a @array DataObj */
$this->setNotExistsFields();
try {
/** @class composer */
$UpdateData = new Update;
$UpdateData->ExeUpdate($this->Table,$this->DataObj, "WHERE id=:id", "id={$this->Fields['id']}");
/** @method Update updateSession() Update the currenctly session with a new email */
$this->updateSession();
/** @return Exception */
if($UpdateData->getResult()):
endif;
} catch (Exception $ex) {
/** @return */
}
endif;
}
}E a maneira correta de se trabalhar com o try catch seria essa
try {
/** @class composer */
$ReadItens = new Read;
$ReadItens->ExeRead($this->Table, '*', "WHERE {$this->Itens} AND id != :id", $this->Parse . "&id={$this->DataObj['id']}");
/** @return Error Not an Excepetion */
if($ReadItens->getResult()):
$this->Errors=['erros' => "Campo Esse registro já existe.#exibir_erros"];
echo json_encode($this->Errors);
endif;
} catch (Exception $e) {
/** @return */
}Consegui uma semântica melhor porém o exception não é passado
try {
/** @class composer */
$UpdateData = new Update;
$UpdateData->ExeUpdate($this->Table,$this->DataObj, "WHERE id=:id", "id={$this->Fields['id']}");
/** @method Update updateSession() Update the currenctly session with a new email when it exists */
$this->updateSession();
if($UpdateData->getResult()):
/** @throws Exception */
throw new Exception("Registro atualizado com sucesso.", E_USER_NOTICE);
endif;
} catch (Exception $ex) {
/** @return json Message successful for AJAX interaction */
$this->Success=['sucesso' => $e];
echo json_encode($this->Success);
}
O jSON retorna
sucesso null
Quando eu faço um
throw new Exception("Registro atualizado com sucesso.", E_USER_NOTICE); eu estou armazenando o erro para ser tratado no catch na variável, nesse caso, $e ? Ou seja, eu armazeno essa mensagem em $e bem como posso pegar o código do erro, o arquivo , etc ... ?
Desculpa se estou postando muito é que estou empolgado com essa bagaça e quero ver ela funcionando. Meu presente de aniversário AUAHAUHAUHUAHUA
Essa é a versão que finalizei aqui porque tenho que sair
<?php
ini_set('display_errors',0);
ini_set('display_startup_erros',0);
/**
* <b>ChangeMySQLTableRows.class [ Change Rows Table ]: </b>
* Altera uma ou mais linhas da tabela MySQL definida na variável private $Table
* Os comandos podem ser tanto
*
* @copyright (c) 2015, Samuel dos Santos Programação Criativa
*/ private $DataCadastro;
/** @var Table The table where the data are change */
private $Table;
/** @array Fields Container for params coming from $_POST form */
private $Fields;
/** @array DataObj Container for @array Fields */
private $DataObj;
/** @var Erros The error message */
private $Errors;
/** @var Success The success message */
private $Success;
/** @array Itens To check if the record is duplicated before inserting it */
private $Itens;
/** @var Pase To create a bind values for @var Itens */
private $Parse;
/**
* @__contruct Required @var Table what receive changes,
* @array Fields what it contains all $_POST itens from form,
* @array Itens Optional if you want to compare fields existings report it in forma ['item' => $Post['field']]
*
*/
function __construct($Table, array $Fields, $Itens = null) {
$this->Table = $Table;
$this->Fields = $Fields;
$this->Itens = $Itens;
$this->DataCadastro = new \DateTime();
$this->DataObj = $this->Fields;
/** @method friendUrlModelProduct() */
$this->friendUrlModelProduct();
/** @method RemoveMask() */
$this->removeMask();
/** @method encodingSha1() */
$this->encodingSha1();
/** @method checkPassActual() */
$this->checkPassActual();
/** @method setErros() */
$this->setErros();
/** @method setActions() */
$this->setActions();
}
/************************************************************
* ********************** Private methods **********************/
/**
/**
* <b>setErros: </b> Set the errors and return from JSON
*
* @return Exception
*/
private function setErros() {
// Validação para tela de alteração de dados
if($this->DataObj['action']!='validate_data_access'):
// Faz a validação dos campos fora da tela de alteração de dados
foreach($this->Fields as $Indice => $Val):
// Lançamos os campos com exceções, ou seja, com preenchimento opcional
if($Indice != 'action' && $Indice != 'id' && empty($Val) && $Indice != 'garantia' && $Indice != 'link' && $Indice != 'id_sub1' && $Indice != 'id_sub2' && $Indice != 'id_sub3'):
$this->Errors=['erros' => "Campo obrigatório#{$Indice}"];
echo json_encode($this->Errors);
exit;
endif;
endforeach;
endif;
}
/**
* <b>createBindValues: </b> Create bindValues in format :bind | =value to check that the record alread exists in $var Table
* on this method @checkAlreadyExists
*
* @return array Return the bindValues for the query
*/
private function createBindValues() {
foreach($this->Itens as $Itens => $Val):
$this->Itens .= $Itens . ' =:' . $Itens . ' AND ';
$this->Parse .= $Itens . '=' . $Val . '&';
endforeach;
$this->Itens = substr($this->Itens, 0, strrpos($this->Itens, 'AND'));
$this->Parse = substr($this->Parse, 0, strrpos($this->Parse, '&'));
$this->Itens = str_replace('Array', '', $this->Itens);
}
/**
* <b>checkAlreadyExists: </b> Compare the @array Iten[key] whith @var Iten[val]
* If match it that mean the row already exists in the @var Table so the method stop and return throw new Exception
*
* @return Exception in case of error or booleano
*/
private function checkAlreadyExists() {
if(!empty($this->Itens)):
/** Set id = 0 when this not isset and make the query works correctly */
if(!isset($this->DataObj['id'])):
$this->DataObj['id'] = 0;
endif;
/** @method createBindValues()*/
$this->createBindValues();
try {
/** @class composer */
$ReadItens = new Read;
$ReadItens->ExeRead($this->Table, '*', "WHERE {$this->Itens} AND id != :id", $this->Parse . "&id={$this->DataObj['id']}");
if($ReadItens->getResult()):
/** @throws Exception */
throw new Exception("Esse registro já existe.", E_USER_NOTICE);
endif;
} catch (Exception $e) {
/** @return json Message successful for AJAX interaction */
$this->Errors=['erros' => "Esse registro já existe.#exibir_erros"];
echo json_encode($this->Errors);
}
else:
return true;
endif;
}
/**
* <b>changeDataUser: </b> Check for content in a input
* Try if all this is null if not, try if either is empty and return the message error
*
* @return Exception
*/
private function changeDataUser() {
if($this->DataObj['action']=='validate_data_access'):
if(empty($this->DataObj['email']) && empty($this->DataObj['senha'])):
$this->Errors=['erros' => "Preencha ou o campo com o novo e-mail ou o campo com a nova senha. E informe a senha atual para concluir.#exibir_erros"];
echo json_encode($this->Errors);
elseif(!empty($this->DataObj['email']) && empty($this->DataObj['senha']) && empty($this->DataObj['atual_pass'])):
$this->Errors=['erros' => "Tudo certo. Basta informar sua senha atual.#exibir_erros"];
echo json_encode($this->Errors);
elseif(empty($this->DataObj['email']) && !empty($this->DataObj['senha']) && empty($this->DataObj['atual_pass'])):
$this->Errors=['erros' => "Tudo certo. Basta informar sua senha atual.#exibir_erros"];
echo json_encode($this->Errors);
endif;
endif;
}
/**
* <b>fFriendUrlModelProduct: </b> Transforms the product model to work with url's friendly
*
* @return array Increment the @array DataObj with a new index
*/
private function friendUrlModelProduct() {
if(isset($this->DataObj['modelo']) && !empty($this->DataObj['modelo'])):
$Funcoes=new Valid;
$this->DataObj['modelo_tratado'] = $Funcoes->retira_acentos(utf8_decode($this->DataObj['modelo']), '-');
endif;
}
/**
* <b>removeMask: </b> Remove the characters aditionais from maks plugin jQuery
*
* @return array All set fields without the characters from mask
*/
private function removeMask() {
if(isset($this->DataObj['preco']) && !empty($this->DataObj['preco'])):
$this->DataObj['preco'] = str_replace('.', '', $this->DataObj['preco']);
$this->DataObj['preco'] = str_replace(',', '.', $this->DataObj['preco']);
endif;
foreach($this->DataObj as $IndiceObj):
if($IndiceObj=='cnpj' || $IndiceObj=='cpf' || $IndiceObj=='cep' || $IndiceObj=='telefone'):
$this->DataObj = str_replace(['_', '-', '.', '/'], '', $this->DataObj);
endif;
endforeach;
}
/**
* <b>encodingSha1</b> Encoding password fields with sha1
*
* @return array Change field passwords value in @array DataObj with value encoding by sha1
*/
private function encodingSha1() {
if(isset($this->DataObj['senha']) && !empty($this->DataObj['senha'])):
$this->DataObj['senha'] = sha1($this->DataObj['senha']);
endif;
}
/**
* <b>checkPassActual:</b> Check if this actual password value is true
*
* @return json $erros Caso a senha esteja incorreta
*/
private function checkPassActual() {
if(isset($this->DataObj['atual_pass']) && !empty($this->DataObj['atual_pass'])):
/** @return Encoding actual password by sha1 */
$this->DataObj['atual_pass'] = sha1($this->DataObj['atual_pass']);
try{
/** @class composer */
$ReadPass = new Read;
$ReadPass->ExeRead('rio_clientes', 'senha,id,email', 'WHERE senha = :senha_atual', "senha_atual={$this->DataObj['atual_pass']}");
if(!$ReadPass->getResult() && empty($this->Success)):
/** @throws Exception */
throw new Exception("A senha atual está incorreta.", E_USER_NOTICE);
endif;
} catch (Exception $e) {
/** @return json Message successful for AJAX interaction */
$this->Errors=['erros' => "A senha atual está incorreta.#exibir_erros"];
echo json_encode($this->Errors);
}
endif;
}
/**
* <b>unsetFields: </b> Unset index from @array Dataobj with a specif rules
*
* @return array @array DataObj with removeds indexes
*/
private function unsetFields() {
/** @return Remove the index from @array DataObj */
unset($this->DataObj['id']);
unset($this->DataObj['action']);
unset($this->DataObj['atual_pass']);
/** @return Remove the index email from @array DataObj if is null */
if(empty($this->DataObj['email'])):
unset($this->DataObj['email']);
endif;
/** @return Remove the index senha from @array DataObj if is null */
if(empty($this->DataObj['senha'])):
unset($this->DataObj['senha']);
endif;
}
/**
* <b>setActions: </b> Execute the principals methods
* Can be a insert or a update in a @var Table
*
* @return Exception Container a message success
*/
private function setActions() {
/** @method unset unsetFields() Remove indexes from @array DataObj */
$this->unsetFields();
/** @method Insert insertNewRow() Insert a new record in a @var Table */
if(!isset($this->Fields['id']) || empty($this->Fields['id'])):
$this->insertNewRow();
/** @method Update updateNewRow() Update a new record in a @var Table */
else:
$this->updateNewRow();
endif;
}
/**
* <b>setNotExistsFields: </b> Create a new indexes in a @array DataObj
*
* @return array @array DataObj with the new indexes
*/
private function setNotExistsFields() {
if(!empty($this->DataObj['senha'])):
$this->DataObj['data_alteracao_senha'] = $this->DataCadastro;
endif;
}
/**
* <b>updateSession: </b> Update index session when e-mail is update in a @var Table
*
* @return array New email value for currenctly session
*/
private function updateSession() {
if(!empty($this->DataObj['email'])):
/** @class composer */
$sessao = new Session;
/** @return array New value for set index $_SESSION */
$_SESSION['logado'] = $this->DataObj['email'];
endif;
}
/**
* <b>insertNewRow: </b> Insert a new row in a @var Table
*
* @return boolean
*/
private function insertNewRow() {
if($this->checkAlreadyExists()==true):
try {
$InsertData = new Create;
$InsertData->ExeCreate($this->Table, $this->DataObj);
/** @return Exception Message successful */
if($InsertData->getResult()):
/** @throws Exception */
throw new Exception("Registro inserido com sucesso.", E_USER_NOTICE);
endif;
} catch (Exception $e) {
/** @return json Message successful for AJAX interaction */
$this->Success=['sucesso' => 'Registro inserido com sucesso.'];
echo json_encode($this->Success);
}
endif;
}
/**
* <b>updateNewRow: Update a exists row in a @var Table</b>
*
* @return boolean
*/
private function updateNewRow() {
if($this->checkAlreadyExists()==true):
/** @methos Create setNotExistsFields() Create new indexes in a @array DataObj */
$this->setNotExistsFields();
try {
/** @class composer */
$UpdateData = new Update;
$UpdateData->ExeUpdate($this->Table,$this->DataObj, "WHERE id=:id", "id={$this->Fields['id']}");
/** @method Update updateSession() Update the currenctly session with a new email when it exists */
$this->updateSession();
if($UpdateData->getResult()):
/** @throws Exception */
throw new Exception("Registro atualizado com sucesso.", E_USER_NOTICE);
endif;
} catch (Exception $e) {
/** @return json Message successful for AJAX interaction */
$this->Success=['sucesso' => 'Registro atualizado com sucesso.'];
echo json_encode($this->Success);
}
endif;
}
}É importante se impolgar, pois, apesar de exigir muito trabalho, é bem satisfatório. Vamos aos trabalhos iniciais.
Documentation phpDoc
O phpDoc, além de documentar o código, supre alguns pontos que o PHP deixa de lado. Um deles é a tipagem de dados e retorno.
Comentários do phpDoc sempre devem estar em blocos de comentários (DocBLock). Então comentários de uma linha não são válidos. Como o comentário abaixo.
/** @var DateTime Tell him, what time is it ? */
private $DataCadastro;
o phpDocumentor se baseia, principalmente, em annotations dentro dos DocBlocks, toda a lista de annotations disponíveis você pode visualizar no link acima da documentação do phpDoc.
Falando sobre a @var, após a annotation, deve vir o tipo da variável e, de forma opcional, sua descrição. Nesta parte abaixo, está incorreta:
/** @array Fields Container for params coming from $_POST form */
private $Fields;
O correto deveria ser:
/**
* @var array Fields Container for params coming from $_POST form
*/
private $Fields;
Outro ponto interessante, é que você pode identificar o tipo que será utilizado dentro do array, tal como um array de strings:
/**
* @var string[]
*/
Um array de vários tipos:
/**
* @var mixed[]
*/
Um vetor (array de multipla dimensão):
/**
* @var array[]
*/
E, também, um conjunto de valores:
/**
* @var string|null
*/
Nesse último exemplo, é explícito que o valor só pode ser entre string ou null.
Outra parte dos comentários, é sua utilidade. Comentários devem complementar a leitura do código, e não repeti-la. Em todas as linhas, abaixo copiadas, você está sendo redundante, comentando o que o próprio código já está me dizendo.
/** @method friendUrlModelProduct() */
$this->friendUrlModelProduct();
/** @method RemoveMask() */
$this->removeMask();
/** @method encodingSha1() */
$this->encodingSha1();
/** @method checkPassActual() */
$this->checkPassActual();
/** @method setErros() */
$this->setErros();
/** @method setActions() */
$this->setActions();
Outros pontos de comentários redundantes:
/************************************************************
* ******************** Private methods ********************/
/** @throws Exception */
O @throws deve ser utilizado, mas não aonde ele está e sim na assinatura do método:
/**
* <b>insertNewRow: </b> Insert a new row in a @var Table
*
* @return boolean
* @throws \Exception If cannot insert a new row
*/
private function insertNewRow() {
Seguindo o mesmo padrão, o tipo da exception lançada e, opcionalmente, a sua descrição.
Codificação:
Colocar as propriedades em lowerCamelCase e, de preferência, em inglês. Anteriormente eu não comentei, mas não é uma necessidade ser em inglês, mas é importante seguir um padrão e, já que a linguagem de programação é em inglês, facilita bastante tudo ser em inglês:
/**
* @var DateTime
*/
private $dateInsert;
/**
* @var string
*/
private $table;
/**
* @var string[]
*/
private $fieldList;
É uma convenção, ajuda bastante na leitura.
Outro ponto, não anteriormente comentado, não abrevie nada. O código em si deve dizer o que ele se propõe. Logo, não é bom ver nada disso aqui:
private $DataObj;
São apenas algumas "letrinhas" a mais e que, para a compreensão, fazem uma enorme diferença:
private $dataObject;
Por enquanto é o que eu pude escrever com o tempo disponível que eu possuo. Assim que tiver mais tempo, passarei mais detalhes.
Como sugestão, leia e aplique os links abaixo (são os mais importantes nesse momento):
http://pt.slideshare.net/guilhermeblanco/phpubsp-object-calisthenics-aplicado-ao-php?next_slideshow=1
http://pt.slideshare.net/guilhermeblanco/php-para-adultos-clean-code-e-object-calisthenics
PSR - 1: http://www.php-fig.org/psr/psr-1/
PSR - 2: http://www.php-fig.org/psr/psr-2/
Suas dicas são boas Gabriel. Sei que não consegui eliminar todas as falhas, porque realmente li todas as referência que você me passou, mas, está funcionando agora perfeitamente e atende como eu esperava. Aliás, está orientado a objetos e tudo que eu fazia manualmente e "proceduralmente" não é mais necessário. Viva o/
Se quiser avaliar novamente ignorando alguns poucos métodos que fogem da regra de manter apenas um nível de indentação e um ou outro que utilizam o else e o elseif, fique a vontade. Suas críticas são muito construtivas e ajudaram a melhorar meu código então, quanto mais melhor =)
<?php
/**
* <b>ChangeMySQLTableRows.class [ Change Rows Table ]: </b>
* Altera uma ou mais linhas da tabela MySQL definida na variável private $Table
* Os comandos podem ser tanto
*
* @copyright (c) 2015, Samuel dos Santos Programação Criativa
*/ private $actualData;
/**
* @var string $table The table will receive changes
*/
private $table;
/**
* @var array $fields It contains the data coming from form
*/
private $fields;
/**
* @var mixed[] $dataObject It contains the same values in the @table
* but it is usage for eliminate indexes before insert or update any data
*/
private $dataObject;
/**
* @var string | null $errors It contains the message error, when exist
*/
private $errors;
/**
* @var string | null $success It contains the message success, when exist
*/
private $success;
/**
* @var mixed[] $itens Stores the values to compare if the record
* already exists in the @table
*/
private $itens;
/**
* @var string $parse Stores the bind values for compare in query
* when we need to check if the record already exists in the @table
*/
private $parse;
/**
* This contructor require an @var string $table, an @var array $fields and optional @var mixed[] $itens
* for initializate the class correctly and work well. And finaly this call the principal methods for work with it
*/
function __construct($table, array $fields, $itens = null) {
$this->table = $table;
$this->fields = $fields;
$this->itens = $itens;
$this->actualData = new DateTime();
$this->dataObject = $this->fields;
/**
* Call the methods in order of execute
*/
$this->changeDataUser();
$this->friendUrlModelProduct();
$this->removeMask();
$this->encodingSha1();
$this->checkPassActual();
$this->checkAlreadyExists();
$this->setErros();
$this->setActions();
}
/**
* <b>setErros: </b> Set the errors and return if from AJAX
* This return will be focus the fiel id pass in second param object
* This work well like this:
* we explode this json and stores it in an new array where index[0] contains the message
* and index[1] contains the field what we are focus and change a background
*
* @return \Exception Return this error in json format
*/
private function setErros() {
if($this->dataObject['action']!='validate_data_access'):
foreach($this->fields as $Indice => $Val):
if($Indice != 'action' && $Indice != 'id' && empty($Val) && $Indice != 'garantia' && $Indice != 'link' && $Indice != 'id_sub1' && $Indice != 'id_sub2' && $Indice != 'id_sub3'):
$e = new Exception("Campo obrigatório#{$Indice}", E_USER_NOTICE);
$this->errors=['erros' => $e->getMessage()];
echo json_encode($this->errors);
exit;
endif;
endforeach;
endif;
}
/**
* <b>createBindValues: </b> Create bindValues in format :bind | =value to check that the record alread exists in $var Table
* on this method @checkAlreadyExists
*
* @return array Return the bindValues for the query
*/
private function createBindValues() {
foreach($this->itens as $itens => $val):
$this->itens .= $itens . ' = :' . $itens . ' AND ';
$this->parse .= $itens . '=' . $val . '&';
endforeach;
$this->itens = substr($this->itens, 0, strrpos($this->itens, 'AND'));
$this->parse = substr($this->parse, 0, strrpos($this->parse, '&'));
$this->itens = str_replace('Array', '', $this->itens);
}
/**
* <b>checkAlreadyExists: </b> Compare the @array Iten[key] whith @var Iten[val]
* If match it that mean the row already exists in the @var Table so the method stop and return throw new Exception
*
* @return \Exception Case this params match
*/
private function checkAlreadyExists() {
if(!empty($this->itens)):
try {
if(!isset($this->dataObject['id'])):
$this->dataObject['id'] = 0;
endif;
$this->createBindValues();
$ReadItens = new Read;
$ReadItens->ExeRead($this->table, '*', "WHERE {$this->itens} AND id != :id", $this->parse . "&id={$this->dataObject['id']}");
if($ReadItens->getResult()):
throw new Exception("Esse registro já existe.#exibir_erros", E_USER_NOTICE);
endif;
} catch (Exception $e) {
$this->errors=['erros' => $e->getMessage()];
echo json_encode($this->errors);
exit;
}
else:
return true;
endif;
}
/**
* <b>changeDataUser: </b> Check for content in a input
* Try if all this is null if not, try if either is empty and return the message error
*
* @return Exception Return it in json format
*/
private function changeDataUser() {
if($this->dataObject['action']=='validate_data_access'):
if(empty($this->dataObject['email']) && empty($this->dataObject['senha'])):
$this->errors=['erros' => "Preencha ou o campo com o novo e-mail ou o campo com a nova senha. E informe a senha atual para concluir.#exibir_erros"];
echo json_encode($this->errors);
exit;
elseif(!empty($this->dataObject['email']) && empty($this->dataObject['senha']) && empty($this->dataObject['atual_pass'])
|| (empty($this->dataObject['email']) && !empty($this->dataObject['senha']) && empty($this->dataObject['atual_pass']))):
$this->Errors=['erros' => "Tudo certo. Basta informar sua senha atual.#exibir_erros"];
echo json_encode($this->Errors);
exit;
endif;
endif;
}
/**
* <b>fFriendUrlModelProduct: </b> Transforms the product model to work with url's friendly
*
* @return array Increment @var mixed[] $dataObject with the new index
*/
private function friendUrlModelProduct() {
if(isset($this->dataObject['modelo']) && !empty($this->dataObject['modelo'])):
$Funcoes=new Valid;
$this->dataObject['modelo_tratado'] = $Funcoes->retira_acentos(utf8_decode($this->dataObject['modelo']), '-');
endif;
}
/**
* <b>removeMask: </b> Remove the characters aditionais from maks plugin jQuery
*
* @return array All set fields without the characters from mask
*/
private function removeMask() {
if(isset($this->dataObject['preco']) && !empty($this->dataObject['preco'])):
$this->dataObject['preco'] = str_replace('.', '', $this->dataObject['preco']);
$this->dataObject['preco'] = str_replace(',', '.', $this->dataObject['preco']);
endif;
foreach($this->dataObject as $IndiceObj):
if($IndiceObj=='cnpj' || $IndiceObj=='cpf' || $IndiceObj=='cep' || $IndiceObj=='telefone'):
$this->dataObject = str_replace(['_', '-', '.', '/'], '', $this->dataObject);
endif;
endforeach;
}
/**
* <b>encodingSha1</b> Encoding password fields with sha1
*
* @return array Return it encoding by sha1
*/
private function encodingSha1() {
if(isset($this->dataObject['senha']) && !empty($this->dataObject['senha'])):
$this->dataObject['senha'] = sha1($this->dataObject['senha']);
endif;
}
/**
* <b>checkPassActual:</b> Check if this pass actual password value is true
*
* @return \Exception Return it in json format
*/
private function checkPassActual() {
if(isset($this->dataObject['atual_pass']) && !empty($this->dataObject['atual_pass'])):
$this->dataObject['atual_pass'] = sha1($this->dataObject['atual_pass']);
try{
$ReadPass = new Read;
$ReadPass->ExeRead('rio_clientes', 'senha,id,email', 'WHERE senha = :senha_atual', "senha_atual={$this->dataObject['atual_pass']}");
if(!$ReadPass->getResult() && empty($this->success)):
throw new Exception("A senha atual está incorreta.#exibir_erros", E_USER_NOTICE);
endif;
} catch (Exception $e) {
$this->errors=['erros' => $e->getMessage()];
echo json_encode($this->errors);
exit;
}
endif;
}
/**
* <b>unsetFields: </b> Unset indexes from @var mixed[] dataObject
*
* @return array Return it with removed indexes
*/
private function unsetFields() {
unset($this->dataObject['id']);
unset($this->dataObject['action']);
unset($this->dataObject['atual_pass']);
if(empty($this->dataObject['email'])):
unset($this->dataObject['email']);
endif;
if(empty($this->dataObject['senha'])):
unset($this->dataObject['senha']);
endif;
}
/**
* <b>setActions: </b> Execute the principals methods
* Can be a insert or a update in a @var string $table after clean indexes
*
* @return \Exception Contains the message successful
*/
private function setActions() {
$this->unsetFields();
if(!isset($this->fields['id']) || empty($this->fields['id'])):
$this->insertNewRow();
else:
$this->updateNewRow();
endif;
}
/**
* <b>setNotExistsFields: </b> Create a new indexes in a @var mixed[] dataObject
*
* @return array $dataObject with the new indexes
*/
private function setNotExistsFields() {
if(!empty($this->dataObject['senha'])):
$this->dataObject['data_alteracao_senha'] = $this->actualData->format('Y-m-d H:i:S');
endif;
}
/**
* <b>updateSession: </b> Update index session when e-mail is update in a @var string $table
*
* @return array New email value for currenctly session
*/
private function updateSession() {
if(!empty($this->dataObject['email'])):
$sessao = new Session;
$_SESSION['logado'] = $this->dataObject['email'];
endif;
}
/**
* <b>insertNewRow: </b> Insert a new row in a @var string $table
*
* @return boolean
*/
private function insertNewRow() {
try {
$InsertData = new Create;
$InsertData->ExeCreate($this->table, $this->dataObject);
if($InsertData->getResult()):
throw new Exception("Registro inserido com sucesso.", E_USER_NOTICE);
endif;
} catch (Exception $e) {
$this->success=['sucesso' => $e->getMessage()];
echo json_encode($this->success);
exit;
}
}
/**
* <b>updateNewRow: </b> Update a exists row in a @var string $table
* Create the indexes when it not exist but it is necessary for work right
* Updates the session when the email is changed
*
* @return boolean
*/
private function updateNewRow() {
$this->setNotExistsFields();
try {
$UpdateData = new Update;
$UpdateData->ExeUpdate($this->table,$this->dataObject, "WHERE id=:id", "id={$this->fields['id']}");
$this->updateSession();
if($UpdateData->getResult()):
throw new Exception("Registro atualizado com sucesso.", E_USER_NOTICE);
endif;
} catch (Exception $e) {
$this->success=['sucesso' => $e->getMessage()];
echo json_encode($this->success);
exit;
}
}
}Aproveitando o andamento do enredo do filme, tem como fazer isso de forma a manter apenas um nível de indentação?
/** @return array Contains a list of sub3 registry or message not found any itens */
if($post_data['action']=='search_for_sub2'):
try {
$ReadSu3 = new Read;
$ReadSu3->ExeRead('rio_sub3', 'nome,id,sub2', 'WHERE status = :status AND sub2 = :id_sub2 ORDER BY nome', "status=1&id_sub2={$post_data['id_sub2']}");
if($ReadSu3->getResult()):
$array_data = "<option value=\"0\">Selecione</option>";
foreach($ReadSu3->getResult() as $Sub3):
$array_data .= "<option value=\"{$Sub3->id}\">{$Sub3->nome}</option>";
endforeach;
throw new Exception($array_data, E_USER_NOTICE);
else:
throw new Exception("<option value=\"0\">Nenhuma sub de nível 3 encontrada</option>", E_USER_NOTICE);
endif;
} catch (Exception $e) {
echo json_encode($e->getMessage());
}
endif;
Porque pelo que vi, um if else sempre vai acrescentar um tab na indentação do código.
Sempre há, e veja que não vou utilizar ELSE:
Primeiramente, eu vou imaginar que tudo isso fica dentro de um metodo action, então ou colocar dessa forma:
public function action($post_data) {
/** seu código aqui **/
}
Primeiramente, vou separar as responsabilidades, uma vez definida, chamo uma nova action, pois realmente está sendo realizada uma nova ação conforme o IF definido:
public function action($post_data) {
/** @return array Contains a list of sub3 registry or message not found any itens */
if($post_data['action']=='search_for_sub2'):
$this->actionSearchSub2();
endif;
}
Segundo o autor Robert "UncleBob" Martin, tudo dentro de um try, deve ser tratada como "uma só coisa" (realmente ele define dessa maneira). Dessa forma, ele indica para separar em um método a execução do comando que deve ser tratado em caso de uma exceção:
private function actionSearchSub2() {
try {
/** eu adicionei o echo json_encode aqui **/
echo json_encode($this->readSub3());
} catch (Exception $e) {
echo json_encode($e->getMessage());
}
}
E por último, mas não menos importante:
private function readSub3() {
$ReadSu3 = new Read;
$ReadSu3->ExeRead('rio_sub3', 'nome,id,sub2', 'WHERE status = :status AND sub2 = :id_sub2 ORDER BY nome', "status=1&id_sub2={$post_data['id_sub2']}");
if($ReadSu3->getResult()):
throw new Exception("<option value=\"0\">Nenhuma sub de nível 3 encontrada</option>", E_USER_NOTICE);
endif;
$array_data = "<option value=\"0\">Selecione</option>";
foreach($ReadSu3->getResult() as $Sub3):
$array_data .= "<option value=\"{$Sub3->id}\">{$Sub3->nome}</option>";
endforeach;
return $array_data;
}
Veja que, alterei a lógica da sua verificação e coloquei um *early return* na questão de lançamento da exception (removendo, então, o else utilizado). E, mais abaixo, utilize *return $array_data* ao invés do lançamento da exception, pois o fluxo ocorreu conforme o esperado, e não conforme a exception.
O que pode ser modificado, já que existe uma certa duplicação de código, é o seguinte:
private function actionSearchSub2() {
try {
$data = $this->readSub3();
} catch (Exception $e) {
$data = $e->getMessage();
} finally {
echo json_encode($data);
}
}
dessa forma, o output ocorre somente em um lugar e, ainda por cima, cumprindo o fluxo de execução desejado.
Apesar do resultado final ter mais linhas de código, ficou visivelmente mais limpo e mais fácil de ler, uma vez que a execução do código é linear e não mais condicionada.
Sobre o tópico principalmente, eu ainda não esqueci :D
Mas acho que esse exemplo agora, pode ser aplicado ao seu código atual.
Fiz uma atualização
/**
* UpdateData.class [ Helper ]
class UpdateData {
// A data e hora atual