Problem invoking before insert/update callbacks
- Single Page
Posted 09 December 2011 - 23:04 PM
..
$this->grocery_crud->callback_before_insert(array($this,'insert_user_created'));
$this->grocery_crud->callback_before_update(array($this,'update_user_info'));
$output = $crud->render();
..
and here is how my two callback functions are constructed
function insert_user_created($post_array)
{
//echo 'Hello from before Insert ..';
$post_array['user_created'] = $this->session->userdata('username');
$post_array['password'] = md5($_POST['password']);
return $post_array;
}
function update_user_info($post_array, $PKey)
{
//echo 'Hello from before update ..';
$post_array['last_edit_user'] = $this->session->userdata('last_edit_user');
$post_array['last_edit_date_time'] = date("yyyy-dd-mm",time());
return $post_array;
}
but it appears as if the two callback functions are never reached .. even though the records are added/updated without these additional values.
Posted 10 December 2011 - 07:50 AM
I had even tried the example for callback_before_insert, as given here
http://www.grocerycrud.com/crud/example/callback_before_insert
But no luck even with this. It appears as if there is some issue with the CRUD and CI v2.1, this is what I am using. Any help to overcome this will be appreciated.
Posted 10 December 2011 - 08:32 AM
I am trying to make the before insert/update callbacks work for me but don't know why am unable to make it work. I am calling the
..
$this->grocery_crud->callback_before_insert(array($this,'insert_user_created'));
$this->grocery_crud->callback_before_update(array($this,'update_user_info'));
$output = $crud->render();
..
and here is how my two callback functions are constructed
function insert_user_created($post_array)
{
//echo 'Hello from before Insert ..';
$post_array['user_created'] = $this->session->userdata('username');
$post_array['password'] = md5($_POST['password']);
return $post_array;
}
function update_user_info($post_array, $PKey)
{
//echo 'Hello from before update ..';
$post_array['last_edit_user'] = $this->session->userdata('last_edit_user');
$post_array['last_edit_date_time'] = date("yyyy-dd-mm",time());
return $post_array;
}
but it appears as if the two callback functions are never reached .. even though the records are added/updated without these additional values.
[/quote]
Probably your callbacks don't work for some reason in your project. Try a simple think to see if everything works correctly . Try to use the function call_user_func and do something like this in a controller function:
call_user_func(array($this, 'update_user_info'));
and just have a dump message to your function for example
function update_user_info()
{
echo "It works";
}
and see if everything works correctly. If not then you will not be able to have any callback to your project. Try to fix this issue and probably will work
Posted 10 December 2011 - 11:59 AM
[quote]Try to use the function call_user_func [/quote], I did try to use it instead of callback_before_update but ERRORS
Posted 31 December 2011 - 16:30 PM
I'm trying to encrypt the user's password as below, but it doesn't seem to call the encrypt_pw function at all.
I've trued using call_user_func as suggested and that does work.
Thanks
function crud_users() {
$this->grocery_crud->set_table('Users');
//$this->grocery_crud->change_field_type('pw', 'password');
$this->grocery_crud->display_as('pw','Password');
$this->grocery_crud->callback_before_insert(array($this,'encrypt_pw'));
$output = $this->grocery_crud->render();
$this->load->view('admin',$output);
}
function encrypt_pw($post_array) {
if(empty($post_array['pw'])) {
$post_array['pw'] = SHA1($_POST['pw']);
}
return $post_array;
}
EDIT: I've also just tried doing this via validation rules:
$this->grocery_crud->set_rules('pw', 'Password', 'trim|required|sha1');
In the documentation you say that this function works the same way as the codeigniter function, which allows PHP functions to be used as a rule ('trim' and 'sha1' in this case). 'trim' works but 'sha1' doesn't seem to work here.
Posted 15 January 2012 - 14:06 PM
So what I am saying is as far as I can work out callback_before_insert and callback_after_insert don't work together, help would be appreciated.
Posted 15 January 2012 - 20:41 PM
Hi, I've just started using grocery crud (it's amazing btw!) and I'm having a similar problem.
I'm trying to encrypt the user's password as below, but it doesn't seem to call the encrypt_pw function at all.
I've trued using call_user_func as suggested and that does work.
Thanks
function crud_users() {
$this->grocery_crud->set_table('Users');
//$this->grocery_crud->change_field_type('pw', 'password');
$this->grocery_crud->display_as('pw','Password');
$this->grocery_crud->callback_before_insert(array($this,'encrypt_pw'));
$output = $this->grocery_crud->render();
$this->load->view('admin',$output);
}
function encrypt_pw($post_array) {
if(empty($post_array['pw'])) {
$post_array['pw'] = SHA1($_POST['pw']);
}
return $post_array;
}
EDIT: I've also just tried doing this via validation rules:
$this->grocery_crud->set_rules('pw', 'Password', 'trim|required|sha1');
In the documentation you say that this function works the same way as the codeigniter function, which allows PHP functions to be used as a rule ('trim' and 'sha1' in this case). 'trim' works but 'sha1' doesn't seem to work here.
[/quote]
You have a wrong logic it has to be if(!empty and not if(empty . So the right one is the below:
function encrypt_pw($post_array) {
if(!empty($post_array['pw'])) {
$post_array['pw'] = SHA1($_POST['pw']);
}
return $post_array;
}
As for the sha1, I think you are right. Codeigniter not only validates but also filter the values. I didn't knew that actually. So that's why the sha1 doesn't work , cause I don't take the filtered data from the codeigniter validator. I just check if the validation is correct and then continue with the saving. I will try to have this feature in the next version (1.1.8).
Posted 15 January 2012 - 20:49 PM
I'm having a similar issue I have a controller to create a user, encrypt the password and create an activation key. These two function work fine from a callback before insert, I also want to send an email using a callback after insert, if I add this the page doesn't load and gives a "Call to a member function callback_after_insert()" error, if I remove the callback before insert the callback after works.
So what I am saying is as far as I can work out callback_before_insert and callback_after_insert don't work together, help would be appreciated.
[/quote]
Can you give an example of your functions/methods that you use? I check this scenario and it works.
Posted 16 January 2012 - 00:14 AM
Posted 13 April 2012 - 15:32 PM
any idea??
Posted 13 April 2012 - 21:30 PM
Posted 01 May 2012 - 23:26 PM
web-johnny, the before_insert doesnt work if you add an extra item in the post array (not listed in the add form)
any idea??
[/quote]
I stumbled upon the same problem.
I tried even to create function that will work with references and similar staff but to no result.
Then I checked the insert code (db_insert fnction) in grocery crud. It turns out that the callback_before_insert is called before actual insert is done, but if the additional key => value pairs are added it will ignore them since the for loop
[color=#ff0000]foreach($add_fields as $num_row => $field)[/color]{
...
}
is looping through the fields that are set to be visible in insert form.
So I modified the db_insert function (around the line 695) - checked if there are keys in $post_data that are not present in field list, and if so, I just pass these values to the $insert_data array.
Although this way those extra data are bypassing the field type check, since they're coming from callback function anyway, it works for me.
My Code now look like:
$fieldnames=array(); //added
foreach($add_fields as $num_row => $field)
{
$fieldnames[]=$field->field_name; //added
if(isset($post_data[$field->field_name]) && !isset($this->relation_n_n[$field->field_name]))
{
if(isset($types[$field->field_name]->db_null) && $types[$field->field_name]->db_null && $post_data[$field->field_name] === '')
{
$insert_data[$field->field_name] = null;
}
elseif(isset($types[$field->field_name]->crud_type) && $types[$field->field_name]->crud_type == 'date')
{
$insert_data[$field->field_name] = $this->_convert_date_to_sql_date($post_data[$field->field_name]);
}
elseif(isset($types[$field->field_name]->crud_type) && $types[$field->field_name]->crud_type == 'datetime'){
$insert_data[$field->field_name] = $this->_convert_date_to_sql_date(substr($post_data[$field->field_name],0,10)).
substr($post_data[$field->field_name],10);
}
else
{
$insert_data[$field->field_name] = $post_data[$field->field_name];
}
}
}
//following loop added to copy data to $insert_data array
foreach(array_keys($post_data) as $key){
if(!in_array($key,$fieldnames))
$insert_data[$key] = $post_data[$key];
}
Real fix would be to have full field list from database, and to check the post data against it, not against the field list specified with add_fields.
Probably the same thing could be done for updates.
web-johny thanks for great work on Grocery CRUD
Posted 02 May 2012 - 05:57 AM
That's why I created the type "invisible" field. So for example if you have:
$crud->fields('field1','field2','field3');
$crud->callback_before_insert(array($this,'test_callback'));
and :
function test_callback($post_array){
$post_array['field4'] = 'test';
return $post_array;
}
This will NOT works unless you add the invisible field so you have to do it like this:
$crud->fields('field1','field2','field3','field4');
$crud->change_field_type('field4','invisible');
$crud->callback_before_insert(array($this,'test_callback'));
This is for security reasons so your work around will work but you will have problems with your security as the user can add as many fields as he want without having permission to do it.
Posted 02 May 2012 - 12:22 PM
Somehow I missed that. Thanks.