Send email when you edit a field in Cakephp - cakephp

I have employee application where users standing can be resigned, active, new and transferred. What i would like to achieve is that when the standing of an employee is changed/edited from active (standing_id = 1) it should be able to send through an email but its not. I have put a email function in the EmployeeController. Below is my code.
function _sendNewEmployeeEditMail($id) {
$Employee = $this->Employee->read(null,$id);
$email = new CakeEmail();
$email->from(array('no-reply#test.com' => 'Testing App'));
$email->to(array('jaahvicky#gmail.com' => 'Name Surname'));
$email->subject('New Employee');
$email->template('employee_email');
$email->viewVars(compact('Employee'));
$email->emailFormat('html');
$edit_email = true;
$current_status = $this->Employee->field('standing_id');
if($current_status==1) {
$edit_email = false;
if ($email->send()) {
$this->Session->setFlash('Your employee has been submitted.','default',array('class' => 'notification'));
return true;
} else {
$this->Session->setFlash('Your employee has not been submitted.','default',array('class' => 'error'));
return false;
}
}
}
and in my edit save function here is how i am trying to send the email
public function edit($id = null) {
$this->Employee->id = $id;
if (!$this->Employee->exists()) {
throw new NotFoundException(__('Invalid employee'));
}
if ($this->request->is('post') || $this->request->is('put')) {
if ($this->Employee->save($this->request->data)) {
$this->Session->setFlash(__('The employee has been saved'),'default',array('class' => 'notification'));
$this->_sendNewEmployeeEditMail($this->Employee->getLastInsertID() );
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The employee could not be saved. Please, try again.'),'default',array('class' => 'error'));
}
} else {
$this->request->data = $this->Employee->read(null, $id);
}
$standings = $this->Employee->Standing->find('list');
$this->set(compact('standings'));

You're using $this->Employee->getLastInsertID(), which will only be present after inserting a new Employee.
Because you're editing an existing Employee, this will always be empty. You should use the $id in stead;
$this->_sendNewEmployeeEditMail($id);

Related

Codeigniter 3.1.9 - CI_Session is filling up my database on every refresh

I have been getting back into Codeigniter as support was picked up by BCIT. I have a problem with ci_sessions and the database driver which is regenerating the encrypted session ID and storing new data in my database on every page refresh. I'm so frustrated right now! I have both secure file storage and database for both common drivers. I want to use both or either but the effect on my application is the same whether I am using a database or files. The ci_session keeps refreshing and it is not ideal for logins, registration or any account type. Please help me see what I am doing wrong? Much appreciation granted in advance.
Config:
$config['sess_driver'] = 'database';
$config['sess_cookie_name'] = 'ci_session';
$config['sess_expiration'] = 7200;
$config['sess_save_path'] = 'users';
$config['sess_match_ip'] = FALSE;
$config['sess_time_to_update'] = 300;
$config['sess_regenerate_destroy'] = FALSE;
Controllers:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
* User Management class created by CodexWorld
*/
class Limousers extends CI_Controller {
function __construct() {
parent::__construct();
$this->load->library('form_validation');
$this->load->model('user');
}
/*
* User account information
*/
public function account(){
print_r($_SESSION);
$data = array();
print_r($this->session->userdata());
if($this->session->userdata('isUserLoggedIn')){
$data['user'] = $this->user->getRows(array('id'=>$this->session->userdata('userId')));
//load the view
$this->load->view('limousers/account', $data);
}else{
redirect('limousers/login');
exit;
}
}
/*
* User login
*/
public function login(){
print_r($_SESSION);
if($this->session->userdata('isUserLoggedIn'))
{
print_r($this->session->userdata);
redirect('limousers/account');
exit;
}
$data = array();
if($this->session->userdata('success_msg')){
$data['success_msg'] = $this->session->userdata('success_msg');
$this->session->unset_userdata('success_msg');
}
if($this->session->userdata('error_msg')){
$data['error_msg'] = $this->session->userdata('error_msg');
$this->session->unset_userdata('error_msg');
}
if($this->input->post('loginSubmit')){
$this->form_validation->set_rules('email', 'Email', 'required|valid_email');
$this->form_validation->set_rules('password', 'password', 'required');
if ($this->form_validation->run() == true) {
$con['returnType'] = 'single';
$con['conditions'] = array(
'email'=>$this->input->post('email'),
'password' => md5($this->input->post('password')),
'status' => '1'
);
$checkLogin = $this->user->getRows($con);
if($checkLogin){
$this->session->set_userdata('name',$con['conditions']['email']);
$this->session->set_userdata('isUserLoggedIn',TRUE);
$this->session->set_userdata('userId',$checkLogin['id']);
redirect('limousers/account');
exit;
}else{
$data['error_msg'] = 'Wrong email or password, please try again.';
}
}
}
//load the view
$this->load->view('limousers/login', $data);
}
/*
* User registration
*/
public function registration(){
print_r($_SESSION);
$data = array();
$userData = array();
if($this->input->post('regisSubmit')){
$this->form_validation->set_rules('name', 'Name', 'required');
$this->form_validation->set_rules('email', 'Email', 'required|valid_email|callback_email_check');
$this->form_validation->set_rules('password', 'password', 'required');
$this->form_validation->set_rules('conf_password', 'confirm password', 'required|matches[password]');
$userData = array(
'name' => strip_tags($this->input->post('name')),
'email' => strip_tags($this->input->post('email')),
'password' => md5($this->input->post('password')),
'gender' => $this->input->post('gender'),
'phone' => strip_tags($this->input->post('phone'))
);
if($this->form_validation->run() == true){
$insert = $this->user->insert($userData);
if($insert){
$this->session->set_userdata('success_msg', 'Your registration was successfully. Please login to your account.');
redirect('limousers/login');
exit;
}else{
$data['error_msg'] = 'Some problems occured, please try again.';
}
}
}
$data['user'] = $userData;
//load the view
$this->load->view('limousers/registration', $data);
}
/*
* User logout
*/
public function logout(){
$this->session->unset_userdata('isUserLoggedIn');
$this->session->unset_userdata('userId');
$this->session->sess_destroy();
redirect('limousers/login');
exit;
}
/*
* Existing email check during validation
*/
public function email_check($str){
$con['returnType'] = 'count';
$con['conditions'] = array('email'=>$str);
$checkEmail = $this->user->getRows($con);
if($checkEmail > 0){
$this->form_validation->set_message('email_check', 'The given email already exists.');
return FALSE;
} else {
return TRUE;
}
}
}
Models:
<?php if ( ! defined('BASEPATH')) exit('No direct script access
allowed');
class User extends CI_Model{
function __construct() {
$this->userTbl = 'users';
}
/*
* get rows from the users table
*/
function getRows($params = array()){
$this->db->select('*');
$this->db->from($this->userTbl);
//fetch data by conditions
if(array_key_exists("conditions",$params)){
foreach ($params['conditions'] as $key => $value) {
$this->db->where($key,$value);
}
}
if(array_key_exists("id",$params)){
$this->db->where('id',$params['id']);
$query = $this->db->get();
$result = $query->row_array();
}else{
//set start and limit
if(array_key_exists("start",$params) &&
array_key_exists("limit",$params)){
$this->db->limit($params['limit'],$params['start']);
}elseif(!array_key_exists("start",$params) &&
array_key_exists("limit",$params)){
$this->db->limit($params['limit']);
}
$query = $this->db->get();
if(array_key_exists("returnType",$params) &&
$params['returnType'] == 'count'){
$result = $query->num_rows();
}elseif(array_key_exists("returnType",$params) &&
$params['returnType'] == 'single'){
$result = ($query->num_rows() > 0)?$query- >row_array():FALSE;
}else{
$result = ($query->num_rows() > 0)?$query->result_array():FALSE;
}
}
//return fetched data
return $result;
}
/*
* Insert user information
*/
public function insert($data = array()) {
//add created and modified data if not included
if(!array_key_exists("created", $data)){
$data['created'] = date("Y-m-d H:i:s");
}
if(!array_key_exists("modified", $data)){
$data['modified'] = date("Y-m-d H:i:s");
}
//insert user data to users table
$insert = $this->db->insert($this->userTbl, $data);
//return the status
if($insert){
return $this->db->insert_id();
}else{
return false;
}
}
}

Yii2 saving to db

Yii does not save to db in $register. My aim is to make saving into db and logging a user if he is not there yet or just log in in if he is there.
public function actionLogin()
{
if (!Yii::$app->user->isGuest) {
return $this->goHome();
}
$model = new LoginForm();
if(isset($_POST['LoginForm'])){
$users = User::find()->where("username = '".$_POST['LoginForm']['username']."'")->count();
if ($users == '0'){
$register = new User();
$register->username = 'lak';
$register->save();
}
if ($model->load(Yii::$app->request->post()) && $model->login()) {
return $this->goBack();
}
}
return $this->render('login', [
'model' => $model,
]);
}
could be you have some fails i validation rules
if this the try using
if ($users == '0'){
$register = new User();
$register->username = 'lak';
$register->save(false);
}
if with $register->save(false); the values is saved then check better for your validation rules ..

CakeDC users plugin: redirect error after changePassword

My app is developed in CakePHP 3.x.
I use CakedDC Users plugin, and it works fine, except when the user wants to change his password, and click on Submit.
Let's say we have a Profile ID = 52606b3f-c72d-4485-9c76-3b0f8
The Edit page has a url like this:
localhost/my_app/profile/52606b3f-c72d-4485-9c76-3b0f8
The changePassword page has a url like this:
localhost/my_app/users/users/change-password/52606b3f-c72d-4485-9c76-3b0f8
When I click on Submit, it redirects to the profile page, but the ID is lost:
localhost/my_app/profile
and I get this error message:
Record not found in table "users" with primary key [NULL]
I think the reason is that the ID is not passed. And I don't find where and how to fix it.
Any help please ?.
When id is not passed, the id is taken from the logged in user. You can take a look at src/Controller/Traits/ProfileTrait.php. Could you debug $this->Auth->user('id')?
Also, you could customize the redirect url after changing the password. Configure::write('Users.Profile.route', [{url}]), see src/Controller/Traits/PasswordManagementTrait.php Ln44.
I don't remember my initial code, but, after months, I found the solution.
in src/Controller/Traits/ProfileTrait.php, set $redirect = Configure::read('Users.Profile.route');
public function changePassword()
{
$user = $this->getUsersTable()->newEntity();
$id = $this->Auth->user('id');
if (!empty($id)) {
$user->id = $this->Auth->user('id');
$validatePassword = true;
//#todo add to the documentation: list of routes used
$redirect = Configure::read('Users.Profile.route');
} else {
$user->id = $this->request->session()->read(Configure::read('Users.Key.Session.resetPasswordUserId'));
$validatePassword = false;
if (!$user->id) {
$this->Flash->error(__d('CakeDC/Users', 'User was not found'));
$this->redirect($this->Auth->config('loginAction'));
return;
}
//#todo add to the documentation: list of routes used
$redirect = $this->Auth->config('loginAction');
}
$this->set('validatePassword', $validatePassword);
if ($this->request->is('post')) {
try {
$validator = $this->getUsersTable()->validationPasswordConfirm(new Validator());
if (!empty($id)) {
$validator = $this->getUsersTable()->validationCurrentPassword($validator);
}
$user = $this->getUsersTable()->patchEntity($user, $this->request->data(), ['validate' => $validator]);
if ($user->errors()) {
$this->Flash->error(__d('CakeDC/Users', 'Password could not be changed'));
} else {
$user = $this->getUsersTable()->changePassword($user);
if ($user) {
$this->Flash->success(__d('CakeDC/Users', 'Password has been changed successfully'));
return $this->redirect($redirect);
} else {
$this->Flash->error(__d('CakeDC/Users', 'Password could not be changed'));
}
}
} catch (UserNotFoundException $exception) {
$this->Flash->error(__d('CakeDC/Users', 'User was not found'));
} catch (WrongPasswordException $wpe) {
$this->Flash->error(__d('CakeDC/Users', '{0}', $wpe->getMessage()));
} catch (Exception $exception) {
$this->Flash->error(__d('CakeDC/Users', 'Password could not be changed'));
}
}
$this->set(compact('user'));
$this->set('_serialize', ['user']);
}

Cakephp multiple input fields

I'm a newbie at cakephp. I got a form with 5 inputs. My form should be able to save either one user input or all 5 inputs. I'm able to save when user fills all 5 inputs, however, when user fills only 1 or 2 and saves it. Blank spaces with date created (current date) gets saved in the database. How can i make it to save only the user inputs from the form without any empty fields in the database. My Add function below.
public function add() {
if ($this->request->is('post')) {
$this->Item->create();
for ($i=0;$i<5;$i++){
if(empty($this->request->data['Item'][$i]['name'])){
}else{
$name = $this->request->data['Item'][$i]['name'];
$explode_name = explode(":",$name);
$this->request->data['Item'][$i]['name'] = $explode_name[0];
$this->request->data['Item'][$i]['hrid'] = $explode_name[1];
}
}
if ($this->Item->saveAll($this->request->data['Item'])) {
$this->Session->setFlash(__('The Item has been saved'));
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The item could not be saved. Please, try again.'));
}
}
$itemTypes = $this->Item->ItemType->find('list',array('order' =>array('ItemType.name' => 'asc')));
$this->set(compact('itemTypes'));
}
There is a small thing that you are missing, and it is that whether there is name empty or not but it has a value set for that particular index. You should unset that in case the value is empty as below
public function add() {
if ($this->request->is('post')) {
$this->Item->create();
for ($i=0;$i<5;$i++){
if(empty($this->request->data['Item'][$i]['name'])){
// here we are removing the empty name index so that it does not saves the result
unset($this->request->data['Item'][$i]);
}else{
$name = $this->request->data['Item'][$i]['name'];
$explode_name = explode(":",$name);
$this->request->data['Item'][$i]['name'] = $explode_name[0];
$this->request->data['Item'][$i]['hrid'] = $explode_name[1];
}
}
// also here we should check here that atleast there is one entry
if(!empty($this->request->data['Item'])){
if ($this->Item->saveAll($this->request->data['Item'])) {
$this->Session->setFlash(__('The Item has been saved'));
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The item could not be saved. Please, try again.'));
}
} else {
$this->Session->setFlash(__('There is no such item. Please fill value for at least one item.'));
}
}
$itemTypes = $this->Item->ItemType->find('list',array('order' =>array('ItemType.name' => 'asc')));
$this->set(compact('itemTypes'));
}
Please try the above code.
In CakePHP 2.x you can do it as like below-
public function add(){
if ($this->request->is('post')) {
$this->Item->create();
$items = $this->request->data['Item']; /*Get all items Array*/
$items = array_filter(array_map('array_filter', $items)); /*Remove all empty array, only keep Array with user inputs*/
if ($this->Item->saveAll($items)) {
/*Success*/
} else {
/*Error*/
}
}
}
In CakePHP 3.x you can do it as like below-
public function add() {
if ($this->request->is('post')) {
$items = $this->request->data['Item']; /*Get all items Array*/
$items = array_filter(array_map('array_filter', $items)); /*Remove all empty array, only keep Array with user inputs*/
$entities = $this->Item->newEntities($items); /*Prepare all Data*/
if($this->Item->saveMany($entities)){ /*Save all data*/
/*Success*/
}else{
/*Error*/
}
}
}

How to save a record with associated data

In my application there are 3 types of information:
BrokerInfo
BrokerBank
BrokerDocument
A user should fill out all of the data before it is saved to the database.
What I've tried so far is below, but something is wrong with the transactions as for example BrokerInfo records are being created without BrokerBank records. What is the correct way to store everything or nothing?
public function add() {
if ($this->request->is('post')) {
$this->BrokerInfo->begin();
$this->BrokerInfo->create();
$this->request->data['BrokerInfo']['id'] = String::uuid();
$this->request->data['BrokerInfo']['account_status_id'] = 1;
$this->request->data['BrokerInfo']['db_status_id'] = 1;
if ($this->BrokerInfo->save($this->request->data)) {
$this->BrokerBank->begin();
$this->BrokerBank->create();
$this->request->data['BrokerBank']['broker_info_id'] = $this->request->data['BrokerInfo']['id'];
if($this->BrokerBank->save($this->request->data))
{
$this->BrokerDocument->begin();
$this->BrokerDocument->create();
if($this->BrokerDocument->save($this->request->data))
{
$this->BrokerInfo->commit();
$this->BrokerBank->commit();
$this->BrokerDocument->commit();
$this->Session->setFlash(__('The Broker information has been saved'), 'flash_success');
$this->redirect(array('action' => 'index'));
}
else
{
$this->BrokerInfo->rollback();
$this->BrokerBank->rollback();
$this->BrokerDocument->rollback();
$this->Session->setFlash(__('The customer information could not be saved. Please, try again.'), 'flash_fail');
}
}
else
{
$this->BrokerInfo->rollback();
$this->BrokerBank->rollback();
$this->Session->setFlash(__('The customer information could not be saved. Please, try again.'), 'flash_fail');
}
}
else
{
$this->BrokerInfo->rollback();
$this->Session->setFlash(__('The customer information could not be saved. Please, try again.'), 'flash_fail');
}
}
Use saveAssociated
The code in the question is a user-land implementation of something which already exists: saveAssociated
Model::saveAssociated(array $data = null, array $options = array())
Method used to save multiple model associations at once.
Using saveAssociated the code in the question is no more than:
public function add() {
if (!$this->request->is('post')) {
return;
}
$this->BrokerInfo->create();
$this->request->data['BrokerInfo']['account_status_id'] = 1;
$this->request->data['BrokerInfo']['db_status_id'] = 1;
if ($this->BrokerInfo->saveAssociated($this->request->data)) {
$this->Session->setFlash(...);
return $this->redirect(array('action' => 'index'));
}
$this->Session->setFlash(...);
}
Note that it's not necessary to specify the uuid (use $model->id after save to refer to the new id), and the current hard coded defaults would be better placed in a model beforeSave method unless their values are controller-logic dependent.

Resources