cakephp how can i tell before function from an update - cakephp

I am working on a CakePHP 2.x. The scenario is I am sending an encrypted and decrypted data to the database. So in order to do this I have written beforeSave function in each modal.
so right now the problem is whenever data is updated, the data is not going encrypted into db .. please anyone know how to i fix this issue
I am doing this in my controller. The update and save function:
foreach($data as $datas){
$count = $this->Contact->checkkey($datas['idUser'],$datas['key']);
if($count>0){
$this->Contact->updateContactAgainstkey($datas['name'],
$this->request->data['Contact']['mobileNo'],
$this->request->data['Contact']['other'],
$this->request->data['Contact']['email'],
$datas['key'],$datas['idUser']);
}else{
$this->Contact->create();
$this->Contact->save($this->request->data);
}
}
updateFunction in Model
public function updateContactAgainstkey($name,$mobileNo,
$other,$email,$key,$userid){
if($this->updateAll(
array('name' => "'$name'",
'mobileNo' => "'$mobileNo'",
'workNo' => "'$workNo'",
'homeNo' => "'$homeNo'",
'other' => "'$other'",
'email' => "'$email'",),
array('User_id'=>$userid,'key'=>$key))){
return true;
}else{
return false;
}
}
beforeSave function
public function beforeSave($options=array()) {
if ( isset ( $this -> data [ $this -> alias ] [ 'mobileNo' ] ) ) {
$this -> data [ $this -> alias ] [ 'mobileNo' ] = AllSecure::encrypt($this->data[$this->alias]['email']);
}
return true;
}
please help me if anyone know how to deal with this issue.

Try following code in model
public function updateAll($fields, $conditions = true) {
$db =& ConnectionManager::getDataSource($this->useDbConfig);
$created = FALSE;
$options = array();
if($db->update($this, $fields, null, $conditions)) {
$created = TRUE;
$this->Behaviors->trigger($this, 'afterSave', array($created, $options));
$this->afterSave($created);
$this->_clearCache();
$this->id = false;
return true;
}
return FALSE;
}
look here
http://nuts-and-bolts-of-cakephp.com/2010/01/27/make-updateall-fire-behavior-callbacks/

here better to use save function for updating data like:
$data=array();
$data['Contact']['mobileNo']=$this->request->data['Contact']['mobileNo'];
$data['Contact']['other']=$this->request->data['Contact']['other'];
$data['Contact']['other']=$this->request->data['Contact']['other'];
........... .............. ................
$this->Contact->id = "primerykey";
$this->Contact->save($data);
where $data contains all field that you want to update with value

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;
}
}
}

Persist array store in session symfony

It's been several days since I've been blocking to persist items from an order into session to database.
I stock articles in session in an array and I do not know how to persist the array. I try to convert the array into an object, I can not. This is my service:
public function addArticle($id)
{
$sessionCart = $this->session;
$article = $this->doctrine->getRepository('AppBundle:Article')->find($id);
$cart = $sessionCart->get('cart');
$cart[] = $article;
$sessionCart->set('cart', $cart);
// use later for delivery
$sessionCart->get('commande');
return $sessionCart;
}
public function panier()
{
$articles = $this->session->get('cart');
return $articles;
}
public function delivery(Request $request)
{
$commande = new Commande();
$articles = $this->session->get('cart');
$form = $this->form->create(CommandeType::class, $commande);
if ($request->isMethod('POST') && $form->handleRequest($request)->isValid())
{
$data = $form->getData();
$this->session->set('commande', $data);
$response = new RedirectResponse('payment');
$response->send();
}
return [$form, $articles];
}
public function payment(Request $request)
{
$articles = $this->session->get('cart');
$commande = $this->session->get('commande');
if ($request->isMethod('POST')) {
$em = $this->doctrine;
$em->persist($articles);
$em->persist($commande);
$em->flush();
}
return[$articles, $commande];
}
Error : "EntityManager#persist() expects parameter 1 to be an entity object, array given."
The order is persisted but not the items.
Thanks
I can't understand these two lines
$cart = $sessionCart->get('cart');
$cart[] = $article;
$sessionCart->set('cart', $cart);
$cart is an array and should be an entity isn't it ?
The persist is waiting for an entity,
maybe you can persist in a foreach loop:
foreach($articles as $article){
$em->persist($article);
}
or use a doctrineCollection instead of an array

CakePHP 3.x: log as serialized array

I'm writing my own parser log for CakePHP.
I only need one thing: that is not written a log "message" (as a string), but a serialized array with various log information (date, type, line, stack traces, etc.).
But I don't understand what method/class I should rewrite, although I have consulted the APIs. Can you help me?
EDIT:
For now I do the opposite: I read the logs (already written) and I transform them into an array with a regex.
My code:
$logs = array_map(function($log) {
preg_match('/^'.
'([\d\-]+\s[\d:]+)\s(Error: Fatal Error|Error|Notice: Notice|Warning: Warning)(\s\(\d+\))?:\s([^\n]+)\n'.
'(Exception Attributes:\s((.(?!Request|Referer|Stack|Trace))+)\n)?'.
'(Request URL:\s([^\n]+)\n)?'.
'(Referer URL:\s([^\n]+)\n)?'.
'(Stack Trace:\n(.+))?'.
'(Trace:\n(.+))?(.+)?'.
'/si', $log, $matches);
switch($matches[2]) {
case 'Error: Fatal Error':
$type = 'fatal';
break;
case 'Error':
$type = 'error';
break;
case 'Notice: Notice':
$type = 'notice';
break;
case 'Warning: Warning':
$type = 'warning';
break;
default:
$type = 'unknown';
break;
}
return (object) af([
'datetime' => \Cake\I18n\FrozenTime::parse($matches[1]),
'type' => $type,
'error' => $matches[4],
'attributes' => empty($matches[6]) ? NULL : $matches[6],
'url' => empty($matches[9]) ? NULL : $matches[9],
'referer' => empty($matches[11]) ? NULL : $matches[11],
'stack_trace' => empty($matches[13]) ? (empty($matches[16]) ? NULL : $matches[16]) : $matches[13],
'trace' => empty($matches[15]) ? NULL : $matches[15]
]);
}, af(preg_split('/[\r\n]{2,}/', $logs)));
For now I do the opposite: I read the logs (already written) and with a regex I transform them into an array.
The problem is this is terribly expensive. and that it would be better to do the opposite: to write directly to the logs as a serialized array.
I think what you want to do is write your own LogAdapter.
You simply create a class ArrayLog (extends BaseLog) as mentioned in the docs and configure cakePHP to use it. Within the log function you append the information like $level, $message and $context to a file as an array. This will result in a log file with several arrays that then can be split.
That being said, I would suggest to log to the database and read it out instead of parsing.
Ok, that's it!
(note that this code is absolutely experimental, I have yet to test it properly)
One interesting thing that I want to do: for each log, write to the serialized file and also simultaneously in a plan file.
This allows me either to read logs as a plain text file, or they can be manipulated using the serialized file.
use Cake\Log\Engine\FileLog;
class SerializedLog extends FileLog {
protected function _getLogAsArray($level, $message) {
$serialized['level'] = $level;
$serialized['datetime'] = date('Y-m-d H:i:s');
//Sets exception type and message
if(preg_match('/^(\[([^\]]+)\]\s)?(.+)/', $message, $matches)) {
if(!empty($matches[2]))
$serialized['exception'] = $matches[2];
$serialized['message'] = $matches[3];
}
//Sets the exception attributes
if(preg_match('/Exception Attributes:\s((.(?!Request URL|Referer URL|Stack Trace|Trace))+)/is', $message, $matches)) {
$serialized['attributes'] = $matches[1];
}
//Sets the request URL
if(preg_match('/^Request URL:\s(.+)$/mi', $message, $matches)) {
$serialized['request'] = $matches[1];
}
//Sets the referer URL
if(preg_match('/^Referer URL:\s(.+)$/mi', $message, $matches)) {
$serialized['referer'] = $matches[1];
}
//Sets the trace
if(preg_match('/(Stack )?Trace:\n(.+)$/is', $message, $matches)) {
$serialized['trace'] = $matches[2];
}
$serialized['full'] = date('Y-m-d H:i:s').' '.ucfirst($level).': '.$message;
return (object) $serialized;
}
public function log($level, $message, array $context = []) {
$message = $this->_format(trim($message), $context);
$filename = $this->_getFilename($level);
if (!empty($this->_size)) {
$this->_rotateFile($filename);
}
$pathname = $this->_path . $filename;
$mask = $this->_config['mask'];
//Gets the content of the existing logs and unserializes
$logs = #unserialize(#file_get_contents($pathname));
if(empty($logs) || !is_array($logs))
$logs = [];
//Adds the current log
$logs[] = $this->_getLogAsArray($level, $message);
//Serializes logs
$output = serialize($logs);
if (empty($mask)) {
return file_put_contents($pathname, $output);
}
$exists = file_exists($pathname);
$result = file_put_contents($pathname, $output);
static $selfError = false;
if (!$selfError && !$exists && !chmod($pathname, (int)$mask)) {
$selfError = true;
trigger_error(vsprintf(
'Could not apply permission mask "%s" on log file "%s"',
[$mask, $pathname]
), E_USER_WARNING);
$selfError = false;
}
return $result;
}
}

cakephp 3 controller action -> how to make it smart

I implementet a controller action in the maybe most unelegant way. How could this made better? Table classes are just like after bin/cake bake. I think the part where the Entity is created could be simplyfied very much.
What I'm doing:
Books --belongsTo--> Publishers <--habtm--> Publishernumbers
When adding a Book to the database, the publishernumber is extracted from the ISBN number. This number is then linked to the publisher in a habtm relation. I need this to suggest the user some publishers when typing an isbn in the form.
The code works for now, but in a year, only god will know what I did here. The first part is straightforward.
public function add()
{
$book = $this->Books->newEntity();
$associations = ['associated' =>
[
'Tags',
'Publishers',
'Publishers.Publishernumbers'
]
];
if ($this->request->is('post')) {
$data= $this->request->data;
$publisher = $this->Books->Publishers->get(
$this->request->data['publisher_id'],
['contain' => ['Publishernumbers']]
);
unset($data['publisher_id']);
$book->publisher = $publisher;
//extract group- and publishernumber from the ISBN
$this->loadComponent('Isbn.Isbn');
$split = $this->Isbn->splitIsbn($this->request->data['isbn']);
$publishernumber = $split[1].$split[2];
This is the part where the mess begins. I think this could be done way more elegant.
//check if the publisher contains already the $publishernumber
//and if not, add it to the entity
$new = true;
foreach ($book->publisher->publishernumbers as $n){
if ($n->number == $publishernumber){
$new = false;
}
}
if ($new){
$existingNumber = $this->Books->Publishers->Publishernumbers
->findByNumber($publishernumber)
->first();
if (!$existingNumber){
//publishernumber does not exist in the database
$pubnumber = $this->Books->Publishers->Publishernumbers
->newEntity();
$pubnumber = $this->Books->Publishers->Publishernumbers
->patchEntity($pubnumber, ['number' => $publishernumber]);
$book->publisher->publishernumbers[] = $pubnumber;
} else {
//publishernumber exists in the database
//but is not associated with the publisher
$book->publisher->publishernumbers[] = $existingNumber;
}
$book->publisher->dirty('publishernumbers', true);
}
$book = $this->Books->patchEntity($book, $data, $associations);
Saving
if ($this->Books->save($book, $associations)){
Cache::delete('exlibrisBooksIndex');
$this->Flash->success(__('The book has been saved.'));
return $this->redirect(['action' => 'index']);
} else {
$this->Flash->error(__('Error.'));
}
}
$publishers = $this->Books->Publishers->find('list')
->order('name')
->toArray();
$this->set(compact('book', 'publishers'));
$this->set('_serialize', ['book']);
}

CakePHP 2.5 Datasource, create and return response

I have a specific task to connect CakePHP web application to a remote restful server . I create a datasource, read method works great, but the api after save data return an array of processed data.
Looking for a way to return the data array and use in controller.
My Controller code
public function admin_generate()
{
$data = $this->request->data;
$data['path'] = 'special/generate';
$this->Tool->create();
if($this->Tool->save($data)){
// handle response ????
}
$this->set('data',$data);
$this->set('_serialize','data');
}
In datasource file
public function create(Model $model, $fields = null, $values = null)
{
$data = array_combine($fields, $values);
$api = $this->config['api_path'].$data['path'].'?auth_key='.$this->config['auth_key'];
$json = $this->Http->post($api, $data);
$response = json_decode($json, true);
if (is_null($response)) {
$error = json_last_error();
throw new CakeException($error);
}
return $response; // ??????
}
Can someone show me the correct way to use the api response data in the controller?
I found a solution, a few minutes after a post question. This can help one of you.
datasource
....
if (is_null($response)) {
$error = json_last_error();
throw new CakeException($error);
}
// SOLUTION
$model -> code = $response['code'];
$model -> key = $response['key'];
$model -> code_id = $response['code_id'];
return true;
.....
in controller
.....
if($this->Tool->save($data)){
unset($data['path']);
$data['code'] = $this->Tool->code;
$data['key'] = $this->Tool->key;
$data['code_id'] = $this->Tool->code_id;
}
.....

Resources