validation error messages in BaseController - cakephp

I have a UsersController'S signup action which gathers validation error messages like
if($user->errors()) {
$error_msg = [];
foreach( $user->errors() as $errors) {
if(is_array($errors)){
foreach($errors as $error) {
$error_msg[] = $error;
}
} else {
$error_msg[] = $errors;
}
}
if(!empty($error_msg)){
$this->Flash->error(__(implode("\n \r", $error_msg)) );
}
}
This kind of error messages I want to use in all controllers. This means I have to repeat the same code in all controllers? Or is there a way to write a central function without passing specific entity?

If you want to get model validation in string you can create a component which can be accessed from the controller
Create a component UtilsComponent.php under src/Controller/Component
<?php
namespace App\Controller\Component;
use Cake\Controller\Component;
class UtilsComponent extends Component
{
public function validationError($validationError)
{
$errorMsg = '';
if ($validationError) {
foreach ($validationError as $errorOn => $error) {
$errorMsg .= strtoupper($errorOn) . ': ' . implode(', ', $error) . "\n";
}
} else {
$errorMsg = 'Error Occurred! Try again';
}
return $errorMsg;
}
}
After that you can use this function anywhere in the controller like this
if ($this->Users->save($user)) {
// Do what you want
} else {
$this->Flash->error(__($this->Utils->validationError($user->errors())));
}
Hope this will help

Related

How to unset a laravel session array

Hi I'm trying to remove a product array inside my cart session when the quantity is 1 and user tries to remove it, simply unsets that.
Here is my code:
public function remove($id)
{
if (session('cart')) {
foreach (session('cart') as $product) {
if ($product['id'] == $id) {
if ($product['qty'] == 1) {
} else {
$product['qty'] = $product['qty'] - 1;
}
};
}
Session::put('cart', session('cart'));
return redirect()->back();
}
}
I tried to use Session::forget('cart.'$num) but having some more issues.
Take your session edit it, and then re-set it:
$cart = session('cart');
array_forget($cart, $num);
session()->put('cart', $cart);

Can i convert whole cakephp website to web services?

Hey I m working on project in cakephp. There will also be apps for Android as well as iPhone. How can i convert my web code to web services.
Yes, There is a way to convert complete site in web-services of any version of cakephp.
There is step to follow:
1. Put "Router::parseExtensions("pdf", "json");" this line to your routes.php in config folder before routing rules.
2. Overwrite your "beforeRender" and "Redirect" function in AppController with following:
function beforeRender() {
if (Configure::read("debug") == 0) {
if ($this->name == 'CakeError') {
$this->layout = "error";
}
} else {
if ($this->name == 'CakeError') {
$this->layout = "error";
}
}
if ($this->params["ext"] == "json") {
$paging = $requests = "";
if (isset($this->params["paging"]) && !empty($this->params["paging"])) {
$paging = $this->params["paging"];
}
$this->set(compact("paging"));
if (isset($this->request->data) && !empty($this->request->data)) {
$requests = $this->request->data;
}
$this->set(compact("requests"));
if ($this->Session->check("Message.flash") && is_array($this->Session->read("Message.flash"))) {
foreach ($this->Session->read("Message.flash") as $key => $value) {
$this->set($key, $value);
}
}
if (isset($this->{$this->modelClass}->validationErrors) && !empty($this->{$this->modelClass}->validationErrors)) {
$this->set("formError", $this->{$this->modelClass}->validationErrors);
}
if (isset($this->viewVars["params"])) {
unset($this->viewVars["params"]);
}
if (isset($this->viewVars["request"])) {
unset($this->viewVars["request"]);
}
$response = $this->viewVars;
if (!in_array($this->params["action"], $this->Auth->allowedActions) && !$this->Auth->loggedIn()) {
$response = array("authError" => true, "message" => "Please login to access.");
}
$this->set(compact("response"));
$this->set('_serialize', array("response"));
}
}
public function redirect($url, $status = NULL, $exit = true) {
if ($this->params["ext"] == "json") {
$paging = $requests = "";
if (isset($this->params["paging"]) && !empty($this->params["paging"])) {
$paging = $this->params["paging"];
}
$this->set(compact("paging"));
if (isset($this->request->data) && !empty($this->request->data)) {
$requests = $this->request->data;
}
$this->set(compact("requests"));
if (isset($this->{$this->modelClass}->validationErrors) && !empty($this->{$this->modelClass}->validationErrors)) {
$this->set("formError", $this->{$this->modelClass}->validationErrors);
}
if (!in_array($this->params["action"], $this->Auth->allowedActions) && !$this->Auth->loggedIn()) {
$response = array("authError" => true, "message" => "Please login to access.");
}
$this->set(compact("response"));
$this->set('_serialize', array("response"));
} else {
parent::redirect($url, $status = NULL, $exit = true);
}
}
Note: If you are checking for Ajax request using that request is ajax or not, and you want to response to your ajax, you have to put your response in "IF" condition
if (!isset($this->params["ext"])) {
// echo json_encode($response);
// echo "success";
// die;
}
Otherwise you can render your view in response.
I would start by reading this
You basically need to modify your routes. You also need to modify (serialize) what your controllers return.

Codeigniter - Array dont work correctly

Whenever I call this function, I get the user_id correctly but the password isnt checked...
Model:
<?php
class Prometheus_model extends CI_Model {
var $tables = array(
'bots' => 'bots',
'users' => 'users'
);
function __construct() {
parent::__construct();
}
public function tablename($table = NULL) {
if(! isset($table)) return FALSE;
return $this->tables[$table];
}
public function get($table, $where = array(), $order = NULL) {
$this->db->where($where);
if(isset($order)) {
$this->db->order_by($order);
}
$q = $this->db->get_where($this->tablename($table),$where);
$result = $q->result_array();
// You should use $q->num_rows() to detect the number of returned rows
if($q->num_rows()) {
return $result[0];
}
return $result;
}
public function update($table, $where = array(), $data) {
$this->db->update($this->tablename($table),$data,$where);
return $this->db->affected_rows();
}
public function insert($table, $data) {
$this->db->insert($this->tablename($table),$data);
return $this->db->insert_id();
}
public function delete($table, $where = array()) {
$this->db->delete($this->tablename($table),$where);
return $this->db->affected_rows();
}
public function explicit($query) {
$q = $this->db->query($query);
if(is_object($q)) {
return $q->result_array();
} else {
return $q;
}
}
public function num_rows($table, $where = NULL) {
if(isset($where)){
$this->db->where($where);
}
$q = $this->db->get($table);
return $q->num_rows();
}
public function get_bot_data_by_hw_id($bot_hw_id) {
$q = $this->get('bots', array('bot_hw_id' => $bot_hw_id));
return $q;
}
public function check_user_data($user_incredials, $user_password) {
if($this->num_rows('users', array('user_name' => $user_incredials, 'user_password' => $this->encrypt->decode($user_password))) == 1){
$q = $this->get('users', array('user_name' => $this->security->xss_clean($user_incredials)));
return $q['user_id'];
}
return FALSE;
}
}
?>
My function-calling at the controller:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Login extends CI_Controller {
public function index(){
if($this->input->post('user_login')){
var_dump($this->prometheus_model->check_user_data($this->input->post('user_incredials'), $this->input->post('user_password')));
}
$this->load->view('login_index');
}
}
How can i fixx this ?
In your check_user_data() method you are using
if($this->num_rows('users', array('user_name' => $user_incredials, 'user_password' => $this->encrypt->decode($user_password))) == 1)
I think (logically) following code
$this->encrypt->decode($user_password)
should be
$this->encrypt->encode($user_password)
because, you are calling num_rows() method and it is
public function num_rows($table, $where = NULL)
{
if(isset($where)){
$this->db->where($where);
}
$q = $this->db->get($table);
return $q->num_rows();
}
which is actually querying the data base something like, for example,
select * from USERS where user_name = 'heera' and password = decode('abcde12345')
In this case, the password you are trying to match is need to be encrypted using encode (not decode) method, because the user has given you a non-encrypted (plain) password and the password saved in the database is already encrypted, so encode the plain password using encode method before you query the database to match with already encoded passwords.

Cakephp Render XML errors in custom Exception.renderer

Based on the information here: Using a custom renderer with Exception.renderer to handle application exceptions
I'm creating a custom error renderer that renders in XML format.
Below is the sample code for the render function in app/Lib/Error/AppExceptionRenderer:
public function render() {
if (isset($this->controller->request->params['xml'])) {
$this->controller->viewClass = "MyXml";
$error = array(
'app' => array(
'error' => 'An unexpected error has occured.'
)
);
$this->controller->set('error', $error);
$this->controller->set('_serialize', 'error');
}
}
However nothing gets returned. I have done some echo within the if condition and that shows.
So is it because the viewClass is not initialized while its in AppExceptionRenderer::render() stage?
There were no errors either.
"MyXml" viewClass works perfectly in normal controllers too.
So apparently I was missing the render and send methods.
Here's the full working example.
<?php
class AppExceptionRenderer extends ExceptionRenderer {
public function __construct($exception) {
parent::__construct($exception);
}
public function render() {
// Handle errors
if (isset($this->controller->request->params['xml'])) {
Cakelog::error($this->error->getMessage());
$this->controller->viewClass = "MyXml";
$error = array(
'app' => array(
'error' => 'An illegal operation has been detected.'
)
);
$this->controller->set('error', $error);
$this->controller->set('_serialize', 'error');
$cakeResponseObject = $this->controller->render();
$this->controller->response->send($cakeResponseObject);
} else {
if ($this->method) {
call_user_func_array(array($this, $this->method), array($this->error));
}
}
}
}

cakephp render + afterfilter variables are unset

I am trying to use render for specific action names in my app.
Actually, here are my condition set in my AppController::afterFilter()
if($this->action == 'parameter') {
$this->render('/Elements/parameter');
}
else if($this->action == 'datagrid') {
$this->render('/Elements/datagrid');
}
And in my controller /samples/parameter :
$this->set('model', Inflector::singularize(Inflector::camelize($this->name)));
$this->set('controller', $this->name);
if($parameter_id) {
$this->set('mode', $mode);
$this->set('parameter', $this->Sample->find('first', array('conditions' => array('Sample.id' => $parameter_id))));
} else {
$this->set('mode', 'add');
$this->set('parameter', array());
}
I know that I have to render AFTER the definition of variables, so I use afterFilter Something I don't understand or missed ?
Infos:
I have set in Samples Controller the function
public function afterFilter(){
parent::afterFilter();
}
Thank you all!
The afterFilter() callback is called after rendering process is done, so calling render() inside it is doing it wrong.
If you want to change the view to be rendered do so in beforeRender(). So do something like
if ($this->action == 'parameter') {
$this->view = '/Elements/parameter';
} elseif ($this->action == 'datagrid') {
$this->view = '/Elements/datagrid';
}

Resources