i'm using these two lines to update my table using codeigninter active records
$this->db->where('reference_number', $reference);
$this->db->update('patient', $data);
what i want to de is to check weather it successfully updates the table and according to that i want to give a notification to the user, how can i check the successful update is happened with this lines? there is a no clue in the user guide telling that by putting the line
if($this->db->update('patient', $data));
will give us a true or false value, can we do like that? or is there any other solution to this problem?
regards,
Rangana
You can put a code like this in your model...
function func() {
$this->db->where('reference_number', $reference);
$this->db->update('patient', $data);
$report = array();
$report['error'] = $this->db->_error_number();
$report['message'] = $this->db->_error_message();
return $report;
}
_error_number and _error_message use the mysql_errno and mysql_error functions of php.
Then inside your controller, you can check for the error like this...
$this->load->model("Model_name");
$report = $this->Model_name->func();
if (!$report['error']) {
// update successful
} else {
// update failed
}
In addition, you can also use $this->db->affected_rows() to check if something was actually updated.
Can I just follow on from #ShiVik - if you use the _error_number() or _error_message() functions, you will need to disable automatic database error reporting.
You can do this in /config/database.php. Set db_debug = FALSE.
The way I handle this functionality in my system is just to test the result returned by the ActiveRecord class using something like
if($this->db->update('patient', $data) === TRUE) {
$flash_data = array('type' => 'success', 'message'
=> 'Update successful!');
$this->session->set_flashdata('flash', $flash_data);
}
Although usage of the flash session data system is up to you :) You'd need to add in the relevant front-end to this in your view files, and tweak to your liking etc.
use this
return ($this->db->affected_rows() > 0) ? TRUE : FALSE;
Related
i'm trying to understand up Codeingiter works with entity.
Here's my code from InterventionController.php :
$intervention = $this->interventionsModel->find($id);
$intervention->title = $this->request->getVar("title");
$this->interventionsModel->save($intervention);
-> if i change the title into the form and if i click the "update" button : it works well (database get updates)
-> When i don't change the title and i just click the "update" button : it throws an exception : "There is no data to update."
How can i use codeingiter 4 without getting that exception if no data have been changed by the user ?
Thanks
Save is a wrapper for update/insert. When you know you're updating a record, you can use the update function, pass the variables in and the update will save, regardless of whether the properties of the record have changed.
$intervention = $this->interventionsModel->find($id);
$intervention->title = $this->request->getVar("title");
$this->interventionsModel->update($id, [
"title" => $intervention->title
]);
I think there should be a property of the model that turns this functionality off for the save() wrapper, but it doesn't appear there is.
Documentation: https://codeigniter.com/user_guide/models/model.html?highlight=data%20update#saving-data
try this
$this->obj->update($id, $p);
instead of
$this->obj->where('id',$id)->update( $p);
You can check if the value from form is empty or not and use the IF Condtion
$intervention = $this->interventionsModel->find($id);
if($this->request->getVar("title"))
{
$intervention->title = $this->request->getVar("title");
$this->interventionsModel->save($intervention);
} else {
// title is empty or null;
}
I'm looking at both my code and my result and I don't see any glaring error, so I thought it could be useful to have a few extra sets of eyes look it over.
I have a custom PayPal IPN listener that updates a transaction table in the database. I deployed it Friday before leaving work, and after returning today it seems to be working mostly correctly; but I would like to figure out why one insert behaved strangely.
Here's a capture of the inserts which happened over the weekend:
As you can see, the intended JSON value for the log column of the 4th transaction is empty. I find it strange because the value of the transaction_id column is being parsed from the same array.
Here is the relevant db insert code:
// Generate valid IPN log
private function generateIpnLog () {
global $wpdb;
// prepare log
$array_log = [];
$array_log['verified'] = true;
$array_log['ipn_response'] = (isset($this->PayPal_Response)) ? : 'Error reading from POST array';
// Parse transaction ID
$transaction_id = (isset($this->PayPal_Response['txn_id'])) ? $this->PayPal_Response['txn_id'] : null;
// Generate log
$log = json_encode($array_log);
// Update DB
$wpdb->insert(
'log_paypal',
[
'transaction_id' => ($transaction_id) ? $transaction_id : 'Error getting transaction ID',
'log' => ($log) ? $log : 'Error generating transaction log'
],
[
'%s',
'%s'
]
);
// json log response
$this->json_return = $log;
}
Seeing as the transaction id is parsed fine from the PayPal response, and because we know $array_log['verified'] has an explictly declared value my guess is there must be a problem with json_encode($array_log).
I also checked the data from PayPal IPN history of the PayPal account in question, and can verify there isn't anything different about the way the data is being formed in the null log column vs the others.
Anyone have an idea about what could be happening in this instance?
As suggested by #ishegg it was an encoding issue since PayPal IPN uses windows-1252 encoding and the DB field was encoded in UTF-8.
It was easy to fix in this case since the PayPal return data is not nested / multidimensional (see below).
Called in an earlier function after a PayPal IPN entry is cryptographically verified by the cert chain:
// Process IPN response
$this->PayPal_Response = $this->processIpn();
Then, the function itself:
// Manipulate IPN response and prepare
// for database update and log
private function processIpn () {
// Response ref.
$response = $this->post_array;
if ( isset($response['charset']) ) {
if ($response['charset'] == "windows-1252") {
foreach ($response as $key => $ipn_value) {
$response[$key] = mb_convert_encoding($ipn_value, 'UTF-8', 'Windows-1252');
}
}
}
return $response;
}
Can anyone advice how best to set a temporary variable with scope to be used between hooks?
I have a custom module with the purpose of checking and warning if an attempted file upload matches an existing file on the system.
I am using hook_form_alter to identify the specific upload form and hook_file_validate to check if the file was previously uploaded.
My problem is those two hooks don't share a common parameter - I need to pass information from hook_form_alter back to hook_validate.
The information I want the functions to share is a simple boolean which should be destroyed immediately the file upload is done/dismissed, so using variable_set to persist it to the database is overkill. I don't believe a session or cookie approach is best either.
UPDATES:
Globals approach:
function duplicate_uploads_warning_init(){
$GLOBALS['processed'] = 'testing';
}
function duplicate_uploads_warning_file_validate($file){
drupal_set_message("PROCESSED[file-validate]: {$GLOBALS['processed']}", 'warning');
}
function duplicate_uploads_warning_form_alter(&$form, &$form_state, $form_id){
if( $form_id == 'file_entity_add_upload' ){
drupal_set_message("PROCESSED[form-alter]: {$GLOBALS['processed']}", 'error');
$GLOBALS['processed'] = 'tested';
$form['#validate'][] = 'duplication_validate';
}
}
The code above sets GLOBALS[processed] in the init hook and that value in immediately confirmed in the hook_form_alter.
However the attempt to reassign the value to tested fails. The reassigned value is what I hoped to see in hook_file_validate but I still get the initial value of testing.
Hook_form_alter validation approach:
I tried adding a custom validation function but the upload of the image still took place where I intend to stop it. My code is as follows:
function duplication_validate($form, &$form_state) {
$data = duplicates($form_state['complete form']['upload']['#file']->filename);
if( sizeof($data) > 0 ){
form_set_error('test', 'testing validation');
return false;
}
}
I can confirm my $data variable has content and the sizeof test returns greater than 0.
using variable_set to persist it to the database is overkill
I don't agree they are overkill (you can easily delete variables), and as #2pha have mentioned globals are not recommended. I think you could use variable_set($name, $value), variable_get($name), and variable_del($name) without worrying unless you need to super-optimise your sites database queries. If you really don't want to use the variable_* functions, then maybe cache_set() and cache_get() might work because you can give it a temporary status.
Edit, variables approach:
function duplicate_uploads_warning_init(){
$account = \Drupal::currentUser();
variable_set($account->id() . '_processed', 'testing');
}
function duplicate_uploads_warning_file_validate($file){
$account = \Drupal::currentUser();
$processed_var = variable_get($account->id() . '_processed');
drupal_set_message("PROCESSED[file-validate]: {$processed_var}", 'warning');
}
function duplicate_uploads_warning_form_alter(&$form, &$form_state, $form_id){
if( $form_id == 'file_entity_add_upload' ){
$account = \Drupal::currentUser();
$processed_var = variable_get($account->id() . '_processed');
drupal_set_message("PROCESSED[form-alter]: {$processed_var}", 'error');
variable_set($account->id() . '_processed', 'tested');
$form['#validate'][] = 'duplication_validate';
}
}
… and in a success or #submit callback function run variable_del($account->id() . '_processed') to delete the variable.
maybe $GLOBALS['processed'] was initialized with the static keyword elsewhere....?
I'm using Laravel for a project and want to know how to validate a particular scenario I'm facing. I would like to do this with the native features of Laravel if this is possible?
I have a form which has two questions (as dropdowns), for which both the answer can either be yes or no, however it should throw a validation error if both of the dropdowns equal to no, but they can both be yes.
I've check the laravel documentation, but was unsure what rule to apply here, if there is one at all that can be used? Would I need to write my own rule in this case?
very simple:
let's say both the fields names are foo and bar respectively.
then:
// Validate for those fields like $rules = ['foo'=>'required', 'bar'=>'required'] etc
// if validation passes, add this (i.e. inside if($validator->passes()))
if($_POST['foo'] == 'no' && $_POST['bar'] == 'no')
{
$messages = new Illuminate\Support\MessageBag;
$messages->add('customError', 'both fields can not be no');
return Redirect::route('route.name')->withErrors($validator);
}
the error messge will appear while retrieving.
if you get confuse, just dump the $error var and check how to retrieve it. even if validation passes but it gets failed in the above code, it won't be any difference than what would have happened if indeed validation failed.
Obviously don't know what your form fields are called, but this should work.
This is using the sometimes() method to add a conditional query, where the field value should not be no if the corresponding field equals no.
$data = array(
'field1' => 'no',
'field2' => 'no'
);
$validator = Validator::make($data, array());
$validator->sometimes('field1', 'not_in:no', function($input) {
return $input->field2 == 'no';
});
$validator->sometimes('field2', 'not_in:no', function($input) {
return $input->field1 == 'no';
});
if ($validator->fails()) {
// will fail in this instance
// changing one of the values in the $data array to yes (or anything else, obvs) will result in a pass
}
Just to note, this will only work in Laravel 4.2+
I have two questions related to the FlashMessenger view helper. Both questions are to do this code:
My action method:
private $_messages; // set to $this->_helper->FlashMessenger; in init()
public function loginAction() {
// > login validation <
// Switch based on the result code
switch ($result->getCode()) {
// > snip several cases <
case Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID:
$this->_messages->addMessage("That wasn't the right password.");
break;
case Zend_Auth_Result::SUCCESS:
$this->_messages->addMessage('Logged you in successfully. Welcome back!');
$this->_helper->Redirector('index', 'home');
break;
}
// >snip<
$this->view->messages = $this->_messages->getMessages();
$this->render();
}
My layout (Zend_Layout) view script:
<?php if (isset($this->messages) && count($this->messages) > 0) {
print_r($this->messages);
//$this->partialLoop('partials/messages.phtml', $this->messages);
} ?>
Why is the message not output the first time it is set?
I have a feeling this is to do with the messenger being stored in sessions but I'm sure it's to do with my implementation.
When I submit a bad value to my form I don't get a message until I either send the form again or refresh.
What is a good way of sending this to the PartialLoop helper?
The output of the messenger is something like:
Array(
[0] => 'Message',
[1] => 'Second message' //etc.
)
But this is no good for a PartialLoop as I need to get the message (which needs each message to be an array, containing a 'message' => 'Message string' key/value pair).
Is there a better method instead of rewriting the array before submitting it to the view?
Referring to OIS I'd like to add that you can retrieve the flash-messages within the same request in which they where added to the FlashMessenger. In this case you'd have to use Zend_Controller_Action_Helper_FlashMessenger::getCurrentMessages().
In your case you'd have to change the line
$this->view->messages = $this->_messages->getMessages();
to
$this->view->messages = $this->_messages->getCurrentMessages();
Hope that helps.
Ill quote from the documentation.
10.8.4.4.1. Introduction
The FlashMessenger helper allows you
to pass messages that the user may
need to see on the next request. To
accomplish this, FlashMessenger uses
Zend_Session_Namespace to store
messages for future or next request
retrieval.
Basically, this means that yes you have to refresh the page to see the messages.
Edit for PartialLoop:
You could try this:
foreach ($array as $message) {
$newArray[]['message'] = $message;
}
But you dont have to use PartialLoop. You could send it to Partial and loop it there. Or even loop it right there in your view.