Transaction test mode in CodeIgniter - codeigniter

I saw in the docs about CodeIgniter:
"you can optionally put the transaction system into "test mode", which
will cause your queries to be rolled back -- even if the queries
produce a valid result. To use test mode simply set the first
parameter in the $this->db->trans_start() function to TRUE"
I understand that able to use transaction (test_mode) to support database fixture for testing insert, update, delete. But it still affects to Database. I set db_debug is TRUE.
Any idea about this problem? Thanks so much.
Example code in my controller:
public function __construct(){
//load database library and model
$this->load->library('database');
$this->load->model('message_mdl');
}
public function do()
{
$data_insert = array('message' => 'hello');
$this->db->trans_start(true);
$this->message_mdl->insert($data_insert);
$this->db->trans_complete();
}

I tried this its not working for me too. I don't know why! I'll trying to find the reason. 'll get back here with proper method. If you find it out pls let me know too.
But I tried the alternate method, its working fine.
public function dothis()
{
$data_insert = array('message' => 'hello');
$this->db->trans_begin(); //Manually start transaction.
$this->message_mdl->insert($data_insert);
$this->db->trans_rollback(); //Rollback
}
Make sure that you don't use $this->db->trans_off(); at all.

Related

Eloquent model getRawOriginal() returns new values in `updating` observer

I need to compare original model values with changes that are done when update occurs, but I am not able to do that.
My model update code looks like this:
public function update(array $user, int $userId): ?bool
{
return User::find($userId)->update($user);
}
I thought that the best way to capture changes is to use observer and observe updating event, because I assume it's called right before changes are stored in the database. Here is updating method code:
public function updating(User $user)
{
Log::info('Original user', ['original' => $user->getRawOriginal('status')]);
}
I've tried logging a bit and it seems that updating method gets called after the update happens and then when I try to retrieve original model values there it returns new ones, instead of the original ones.
If I use getChanges() method in updating it returns exactly what has changed, so it seems that changes are tracked somehow, but not the original values?
Can someone give me any pointers how to solve this and explain to me why my approach doesn't work?
Update: Code, where I call update, is wrapped with DB transaction methods. After removing them it seems that updating method gets called at the right time and getRawOriginal then returns expected results.
In this case, what are my options? Is there a way to do what I want without removing transactions?
You can add boot method in your model .Both updating and updated trigger while updating .
protected static function boot()
{
parent::boot();
static::updating(function ($model){
echo "updating";
dump($model->getDirty());
dump($model->getRawOriginal('username'));
});
static::updated(function ($model){
echo "updated";
dump($model->getDirty());
dump($model->getRawOriginal('mobile_number'));
});
}

CodeIgniter sess_destroy does not delete user_data session?

I am creating test case for my CodeIgniter app. However I just found something that I thought should not be happen :
in login.php controller :
public function logout()
{
$this->session->sess_destroy();
redirect('/');
}
So I just created a test to just make sure that session is really destroyed :
public function test_logout()
{
$this->CI = set_controller('login');
// make sure that all session is destroyed
$this->CI->session->set_userdata('test_session', 'some_value');
$this->CI->logout();
// userdata 'test_session' should be removed!
$this->assertTrue(($this->CI->session->userdata('test_session')==null || $this->CI->session->userdata('test_session')==''));
}
However I find that upon running the test case, my test case fails! Upon debug on the last line of test case, I found that the userdata is still exist with value = 'some_value'. I thought that sess_destroy should also delete all the set user data, as per what they described in their website documentation:
This function should be the last one called, and even flash variables will no longer be available. If you only want some items destroyed and not all, use unset_userdata().
I am using Kenji's CIUnit for unit testing.
Is this the correct behaviour or is there something that I missed?
Just found that CIUnit routes the Session to CIU_Session instead of original CodeIgniter's CI_Session. It miss a line that CI_Session does :
$this->userdata = array();
So turns out this is CIUnit's issue instead of CodeIgniter's. Create an issue in their bitbucket page.

How to override save() method in a component

Where and how I am overriding the save method in Joomla 3.0 custom component ?
Current situation:
Custom administrator component.
I have a list view that displays all people stored in table.
Clicking on one entry I get to the detailed view where a form is loaded and it's fields can be edited.
On save, the values are stored in the database. This all works fine.However, ....
When hitting save I wish to modify a field before storing it into the database. How do I override the save function and where? I have been searching this forum and googled quiet a bit to find ways to implement this. Anyone who give me a simple example or point me into the right direction ?
Thanks.
Just adding this for anyone who wants to know the answer to the question itself - this works if you explicitly wish to override the save function. However, look at the actual solution of how to manipulate values!
You override it in the controller, like this:
/**
* save a record (and redirect to main page)
* #return void
*/
function save()
{
$model = $this->getModel('hello');
if ($model->store()) {
$msg = JText::_( 'Greeting Saved!' );
} else {
$msg = JText::_( 'Error Saving Greeting' );
}
// Check the table in so it can be edited.... we are done with it anyway
$link = 'index.php?option=com_hello';
$this->setRedirect($link, $msg);
}
More details here: Joomla Docs - Adding Backend Actions
The prepareTable in the model (as mentioned above) is intended for that (prepare and sanitise the table prior to saving). In case you want to us the ID, though, you should consider using the postSaveHook in the controller:
protected function postSaveHook($model, $validData) {
$item = $model->getItem();
$itemid = $item->get('id');
}
The postSaveHook is called after save is done, thus allowing for newly inserted ID's to be used.
You can use the prepareTable function in the model file (administrator/components/yourComponent/models/yourComponent.php)
protected function prepareTable($table)
{
$table->fieldname = newvalue;
}

CodeIgniter page caching with a exception

I like to use CodeIgniters page caching. But I've got a views counter in the controller, something like:
$this->db->query("UPDATE tb_product SET popularity=popularity+1 WHERE product_id=".$this->db->escape($this->uri->segment(2))."");
Is it possible to use page caching but make a exception to run this query only?
Yes. You could try to implement a hook. This would have to be the 'cache_override' hook. You could do the DB call from the hook.
http://ellislab.com/codeigniter/user-guide/general/hooks.html
Your hook method will have to call the original caching itself after doing the DB call.
function your_hook( )
{
// your DB code here
// Use some CI globals for this, see /system/core/Codeigniter.php
if ($OUT->_display_cache($CFG, $URI) == TRUE)
{
exit;
}
}
You could write a custom Output.php class and override (decorate) the original _display_cache method. Place your MY_Ouput.php in the /application/core directory and CI will use it automatically.
http://ellislab.com/codeigniter/user-guide/general/core_classes.html
Put something like this in it:
class MY_Output extends CI_Output
{
function _display_cache( &$CFG, &$URI )
{
// your DB call
// The original call
return parent::_display_cache( $CFG, $URI );
}
}
I didn't try this myself, but it should help you on your way. One of these will probably work. Good luck!
Thanks for your answer, but I've striped the counter out and wrote a cronjob which will get statistics from Google Analytics trough GAPI.

Customer session is different in different parts of a Magento website

I have a function inside of a Helper in Magento that returns whether or not a customer attribute equals one.
Here is my Helper class
class Nie_Nie_Helper_Data extends Mage_Core_Helper_Abstract {
public function isNieAdmin() {
if(Mage::getSingleton('customer/session')->getCustomer()->getNieAdmin() == 1) {
return true;
} else {
return false;
}
}
}
Now when I call this function from a class that extends Mage_Core_Block_Template, everything seems to work fine. However when I try to use this inside one of my controllers, it does not work. In fact when I do Mage::getSingleton('customer/session')->getCustomer()->debug() the only variable that is returned is the website_id.
Does anyone know what I have to do in order to get this to work?
At the time of the controller the session objects are not yet initialised (although the session variable must be) so it returns a blank model. My guess is the website_id is deliberately set in the creation of a customer object to act as a default.
You could access $_SESSION['customer'] directly to find what you need, but that is messy. An alternative would be to do what you want in an event that occurs later.
I hope someone can come up with a better answer than mine.
Ok it looks like I had to load up the session myself. I had to put the following in my functions:
Mage::getSingleton('core/session', array('name' => 'frontend'));
Hope this helps.

Resources