Codeigniter model with multiple update conditions using manual where statement - php

I have this code in model that returns data
$this->db->select('title, content, date');
$where = "name='Joe' AND status='boss'";
$this->db->where($where);
$query = $this->db->get('mytable');
return $query->result();
I am using a manual where and i wanted to know whether the concept of manual where in updates and possibly in deletes is allowed.
This code updates a table based on a single where condition
$data = array(
'title' => $title,
'name' => $name,
'date' => $date
);
$this->db->where('id', $id);
$this->db->update('mytable', $data);
Is doing this allowed in codeigniter
$data = array(
'title' => $title,
'name' => $name,
'date' => $date
);
$where = "id=$id, name='Joe' AND status='boss'";
$this->db->where($where);
$this->db->update('mytable', $data);

As per document in CodeIgniter Where, you have to mention here with OR or AND "id=$id, name='Joe'.
$where = "id=$id AND/OR name='Joe' AND status='boss'";
^^^^
Chose one
Or use array

Related

How can I get data from 1 Table and 'POST' it to Another Table (CodeIgniter)

I have question. I have 2 different tables, 1st is user and the 2nd is consultation. I want when user make the consultation, the user_id from the 1st table is posted to the 2nd 'user_id' column too.
my controller is like this and I don't know how to do
public function add_detail_consultation()
{
$this->load->helper('date');
$data_consultation['data_consultation'] = $this->db->get('consultation')->row();
$date = date('Y-m-d');
$data = array(
'date' => $date,
'user_id' => //I don't know what to do in this section :(
);
$this->db->insert('consultation', $data);
}
Can you help me? it will help me a lot! thanks
public function add_detail_consultation()
{
$this->load->helper('date');
$data_consultation = $this->db->get('consultation')->row();
$date = date('Y-m-d');
$data = array(
'date' => $date,
'user_id' => $data_consultation['user_id']
);
$this->db->insert('consultation', $data);
}

How to insert a data in a table in CodeIgniter

I'm having some trouble updating records with the Codeigniter framework. I'm using the MVC pattern and active records.
public function save_yarn($data)
{
$this->db->select('sub_name');
$this->db->from('mst_subject');
$this->db->insert($data);
}
This function should works for you:
$data = array(
'title' => $title,
'name' => $name,
'date' => $date
);
$this->db->where('id', $id);
$this->db->update('mytable', $data);
https://ellislab.com/codeigniter/user-guide/database/active_record.html#update
If you're using models for your tables, you can do something easy like
$this->yarn_model->update($row_id_to_update, $data);
Otherwise, Angel's method will work too.

how to make chained model auto read the conditions?

I have two models called Batch and User
Batch has the following
public $belongsTo = array(
'Customer' => array(
'className' => 'User',
'foreignKey' => 'customer_id',
'conditions' => array('Customer.group_id' => CUSTOMERS),
'fields' => '',
'order' => '',
),
);
When I do the following:
$customers = $this->Batch->Customer->find('list');
I fully expected to get back just the users whose group_id matches CUSTOMERS. It returns ALL the records in the users table.
However, I actually have to write
$customers = $this->Batch->Customer->find('list', array('conditions' => array('Customer.group_id' => CUSTOMERS)));
Is there a way so that the chained model User knows that it is called as Customer by Batch and therefore automatically reads the correct conditions in the associations found in Batch model?
I want to make my code more readable hence the motivation for this question.
I want to write simply
$customers = $this->Batch->Customer->find('list');
or something similarly straightforward.
Of course, I realized that if I do the following:
$batches = $this->Batch->find('all');
The condition stated in the associations will be used. But I don't want to find batches. I want to find just customers.
I am using CakePHP 2.4
I think you can't
but you can create custom find types in User model file
public $findMethods = array('customer' => true); //this enable a custom find method named 'customer'
protected function _findCustomer($state, $query, $results = array()) {
if ($state === 'before') {
$query['conditions'] = array('group_id' => CUSTOMERS);
}
return parent::_findList($state, $query, $results);
}
and in BatchesController
$this->Batch->Customer->find('customer');
There are several ways to do this.
1)
do nothing.
Continue to use code like
$customers = $this->Batch->Customer->find('list', array('conditions' => array('Customer.group_id' => CUSTOMERS)));
2)
create a custom find method as suggested by arilia.
3)
write a getCustomers method inside Batch model
where it looks something like this:
public function getCustomers($type, $query = array()) {
if (empty($query['conditions'])) {
$query['conditions'] = array();
}
$query['conditions'] = array_merge($query['conditions'], array('Customer.group_id' => CUSTOMERS));
return $this->Customer->find($type, $query);
}
then you can call
$customers = $this->Batch->getCustomers('list');
UPDATE:
I have written a Plugin that helps with this kind of behavior, utilizing the 3rd solution.
class Batch extends AppModel {
public $name = 'Batch';
public $actsAs = array('UtilityBehaviors.GetAssoc');
public $belongsTo = array(
'Customer' => array(
'className' => 'User',
'foreignKey' => 'customer_id',
'conditions' => array('Customer.group_id' => 7),
'fields' => '',
'order' => '',
),
);
}
You can fetch just the customer data when you are in BatchesController this way:
$customers = $this->Batch->getAssoc('Customer', 'list');
$customers = $this->Batch->getAssoc('Customer', 'all');
$customerCount = $this->Batch->getAssoc('Customer', 'count');
This behavior has tests at travis and you can read about the tests written at github.

Inserting NOW() into Database with CodeIgniter's Active Record

I want to insert current time in database using mySQL function NOW() in Codeigniter's active record. The following query won't work:
$data = array(
'name' => $name ,
'email' => $email,
'time' => NOW()
);
$this->db->insert('mytable', $data);
This is because CodeIgniter’s ActiveRecord class automatically escapes the input.
The following works fine, by calling set() and passing peratmeter FALSE, so that it doesn't escape the NOW().
$data = array(
'name' => $name ,
'email' => $email,
);
$this->db->set('time', 'NOW()', FALSE);
$this->db->insert('mytable', $data);
However, my question is that is there any other way than this? For example, if i can use somehow use by adding everything in the data array only?
For example, something like:
$data = array(
'name' => $name ,
'email' => $email,
'time' => NOW(), FALSE
);
I typically use triggers to handle timestamps but I think this may work.
$data = array(
'name' => $name,
'email' => $email
);
$this->db->set('time', 'NOW()', FALSE);
$this->db->insert('mytable', $data);
Unless I am greatly mistaken, the answer is, "No, there is no way."
The basic problem in situations like that is the fact that you are calling a MySQL function and you're not actually setting a value. CI escapes values so that you can do a clean insert but it does not test to see if those values happen to be calling functions like aes_encrypt, md5, or (in this case) now(). While in most situations this is wonderful, for those situations raw sql is the only recourse.
On a side, date('Y-m-d'); should work as a PHP version of NOW() for MySQL. (It won't work for all versions of SQL though).
aspirinemaga, just replace:
$this->db->set('time', 'NOW()', FALSE);
$this->db->insert('mytable', $data);
for it:
$this->db->set('time', 'NOW() + INTERVAL 1 DAY', FALSE);
$this->db->insert('mytable', $data);
This is the easy way to handle timestamp insertion
$data = array('created_on' => date('Y-m-d H:i:s'));
you can load the date helper and use the codeigniter interal now() if you want to reference the users GMT time offset
it woulk look somewhat like this
$data = array(
'created_on' => date('Y-m-d H:i:s',now())
);
If you don't use the GTM master settings and let your users set their own offsets there is no advantage over using php's time() function.
$data = array(
'name' => $name ,
'email' => $email,
'time' =>date('Y-m-d H:i:s')
);
$this->db->insert('mytable', $data);
According to the source code of codeigniter, the function set is defined as:
public function set($key, $value = '', $escape = TRUE)
{
$key = $this->_object_to_array($key);
if ( ! is_array($key))
{
$key = array($key => $value);
}
foreach ($key as $k => $v)
{
if ($escape === FALSE)
{
$this->ar_set[$this->_protect_identifiers($k)] = $v;
}
else
{
$this->ar_set[$this->_protect_identifiers($k, FALSE, TRUE)] = $this->escape($v);
}
}
return $this;
}
Apparently, if $key is an array, codeigniter will simply ignore the second parameter $value, but the third parameter $escape will still work throughout the iteration of $key, so in this situation, the following codes work (using the chain method):
$this->db->set(array(
'name' => $name ,
'email' => $email,
'time' => 'NOW()'), '', FALSE)->insert('mytable');
However, this will unescape all the data, so you can break your data into two parts:
$this->db->set(array(
'name' => $name ,
'email' => $email))->set(array('time' => 'NOW()'), '', FALSE)->insert('mytable');
putting NOW() in quotes won't work as Active Records will put escape the NOW() into a string and tries to push it into the db as a string of "NOW()"... you will need to use
$this->db->set('time', 'NOW()', FALSE);
to set it correctly.
you can always check your sql afterward with
$this->db->last_query();
Using the date helper worked for me
$this->load->helper('date');
You can find documentation for date_helper here.
$data = array(
'created' => now(),
'modified' => now()
);
$this->db->insert('TABLENAME', $data);
$this->db->query("update table_name set ts = now() where 1=1")
also works for current time stamp!
run query to get now() from mysql i.e select now() as nowinmysql;
then use codeigniter to get this and put in
$data['created_on'] = $row->noinmyssql;
$this->db->insert($data);

Execute params with doctrine using named parameters

I'm encountering a strange problem with doctrine and named parameters.
Here is a query which actually works perfectly with this set of parameters (dynamic in my code):
$params = array( ':id_editeur' => 1,
':nom_editeur' => 'Test');
public function updateById($params)
{
Doctrine_Query::create()
->update('Editeur e')
->set('e.nom_editeur', ':nom_editeur')
->where('e.id_editeur = :id_editeur')
->execute($params);
}
Now i have another function
public function findAll($params)
{
$query = Doctrine_Query::create()
->from('Editeur e')
->orderBy(':orderby')
->limit(':limit')
->offset(':offset');
return $query->execute($params);
}
With these parameters:
$params = array( ':orderby' => ('e.id_editeur ASC'),
':limit' => (10),
':offset' => (20));
And even if it's the same mechanism i get the following error
Invalid parameter number: number of
bound variables does not match number
of tokens
Any idea of the reason? By the way, it works if I fill the orderby, limit and offset directly in the function in the classical way.
The params var cannot contain ":" character...
Try replacing:
$params = array( ':id_editeur' => 1,
':nom_editeur' => 'Test');
to:
$params = array( 'id_editeur' => 1,
'nom_editeur' => 'Test');
Try remove the parenthesis in params array.
$params = array( ':orderby' => 'e.id_editeur ASC',
':limit' => '10',
':offset' => '20');

Categories