How to process multi insertion into a table using single excution - drupal-7

Which is the best way to perform multi insertion into a table using custom code in drupal7.

$segment[] = array('name' => 'test)
$query = db_insert(TABLE_NAME_SEGMENT);
$query->fields( array('name') );
foreach($segment as $value)
$query->values($value);
$query->execute()
finally,I got the solution for it.I don't whether it good or bad

Related

Using query builder to write custom queries like insert, will the usual callbacks still get triggered in CakePHP 3.x?

I was reading through http://book.cakephp.org/3.0/en/orm/query-builder.html
when I found myself wondering if the usual callbacks like Model.afterSave will still triggered if I write a query like this:
$query = $articles->query();
$query->update()
->set(['published' => true])
->where(['id' => $id])
->execute();
What should I do if it does not and I still want to trigger the callbacks while using the query builder to run update operations?
The reason is because I want to update another model called Authors after this query is updated.
The only way to trigger callbacks using a query is by finding each record to update and saving it manually:
$query = $articles->query()->where(...);
foreach ($query as $entity) { $entity->published = true; $articles->save($entity); }

Saving multiple records appropriately cakePHP way

I have an event form which contains information related to event like: start_time, finish_time etc.
Every event bolongs to a user. The requirements are that the same type of event can be saved for multiple users, so from the form I receive a list of users as well.
Now that makes it impossible to use model's native save function and for that reason I have the following code:
function saveNotRepeatedEvents($event, $users){
foreach($users as $user){
$event['Event']['user_id'] = $user;
$this->create();
$this->save($event);
}
return true;
}
First of all, it does not allow for transactions, and I have a feeling that it can be done better, like "cakePHP way", but just cannot find anything during the research.
So the main issue would be how to intruduce transactions in this case. But any help or guidance on how to make it more cakePHP way would be much appreciated.
What you're looking for is Model::saveAll($yourData), which at the end will make use of a transaction (as long as your database engine supports transactions).
The main idea is that you will prepare $yourData as an array with this form
$yourData = array(
array('Event' => array('user_id' => 1)),
array('Event' => array('user_id' => 2)),
);
Of course, you will do this in your for loop, I am just giving you the main idea.

Cakephp : add condition in this->Model->save()

i am working on a cakephp 2.x .want to add a condition into my save query .. for example i want to implement this query
INSERT INTO 'this' where condition is 'this'
right now i am doing this
$count = $this->Message->find('count', array(
'conditions' => array('Message.mobileNo' => $mobileNo,
'Message.body'=>$body
)));
if($count>0){
echo "already have a message";
}else
{
$this->Message->create();
$this->Message->save($this->request->data);
}
at times now i am first checking through count and then saving into the database ... can i add condition into my save so i dont have to query two times into database just to accomplish one task
This is not really CakePHP question rather than MySQL. But you can't do this since the INSERT query doesn't have conditional query.
There are 2 ways of doing it:
As Mark in the comment said use validation. The validation although apply to single field, so it will be quite tricky to do it.
Use beforeValidate() or beforeSave() callbacks in your model to check this and if they return false the save operation wont be executed.
You can put UNIQUE index to your table so it won't allow insertion of phone+message together.
I would go with the method 2.
try the beforeSave methode in your Model
You can use the following code in a better way:
$conditions = array('Message.mobileNo' => $mobileNo,
'Message.body'=>$body);
if ($this->Message->hasAny($conditions)){
echo "already have a message";
}
else{
$this->Message->create();
$this->Message->save($this->request->data);
}

Add a new translatable field to an existing translatable table in CakePHP 2.2

I'm using CakePHP's translatable behavior. I have a few existing fields working fine, but I'm having trouble adding a new translatable field to my model.
CakePHP uses an INNER JOIN to fetch all translatable fields from the database.
Now, if I add an extra translatable field to my model, all the translation records for that field won't exist in the database. And because of the inner join, whenever it tries to fetch ANY existing records from the database, it will return blank - because the INNER JOIN on the new field fails, and so the entire query returns nothing.
Surely people must have come accross this situation before. Is there an easy solution?
One solution would be to edit/override the core and make all the INNER JOIN's into LEFT OUTER JOIN's. Is there anything wrong with that?
Another solution would be to run an update on the translations table to create all the extra records for the new field, every time you add a new translatable field - but I hate that solution.
Is there a better solution? How have others dealt with this problem?
Thanks in advance.
OK, here's a way of making sure the records exist after each time you add a new translatable field. If you've got a better answer, add it, and I'll mark yours as correct.
PS - this is tested for my purposes. I'm using multiple translation tables (http://book.cakephp.org/2.0/en/core-libraries/behaviors/translate.html#multiple-translation-tables). I think it should work for most situations, but if not, it should at least be a good starting point.
In your model (the model that actsAs Translatable), add the following method. What it does is takes an array of locales, and then for every record in the table, and for every translatable field, and for every locale (ie, 3 loops), it checks that a translation record exists. If a translation doesn't exist, it adds a blank one, so at least the INNER JOIN won't fail.
It returns an array of all the records it added, so you can then go through and check them or change their content or whatever.
Here's the model method:
function ensureTranslationIntegrity($localesToCheck){
$allRows = $this->find('all', array('fields' => array('id')));
$fieldsToCheck = array();
$translatableFields = $this->actsAs['Translate'];
foreach($translatableFields as $key => $value){
// actsAs Translatabe can take field names only, or Key => Value pairs - see http://book.cakephp.org/2.0/en/core-libraries/behaviors/translate.html#retrieve-all-translation-records-for-a-field
if(is_numeric($key)){
$field = $value;
} else {
$field = $key;
}
array_push($fieldsToCheck, $field);
}
$translateModel = $this->translateModel();
$addedRows = array(); // This will contain all the rows we have to add
foreach ($allRows as $row){
foreach($fieldsToCheck as $field){
foreach($localesToCheck as $locale){
$conditions = array(
'model' => $this->name,
'foreign_key' => $row[$this->name]['id'],
'field' => $field,
'locale' => $locale
);
$translation = $translateModel->find('first',array('conditions' => $conditions));
if(!$translation){
$data = $conditions; // The data we want to insert will mostly just match the conditions of the failed find
$data['content'] = ''; // add it as empty
$translateModel->create();
$translateModel->save($data);
array_push($addedRows, $data);
}
} // END foreach($localesToCheck as $locale){
} // END foreach($fieldsToCheck as $field){
} // END foreach ($allRows as $row){
return $addedRows;
}
And in your controller, you'd call it something like this:
public function ensure_translation_integrity(){
$locales = array('en_au','en_gb','en_nz','pt_br','xh_za');
$addedRows = $this->YourModel->ensureTranslationIntegrity($locales);
debug($addedRows);
}
Hope that helps someone, but like I said, I'd love to see a better solution if someone has one.

How to retrieve the cakephp used query in find or read

Usually we check the find operation by checking the sql-dump. But it is not possible if query operation done through ajax. How can we check any find operation whick cakePhp done in backgoround and Any way to print it in pr()?
If you give $this->layout='ajax' in the controller code, then it would not show the query.So if you want to view the query , just set the layout to your normal layout (only for testing) and check the query and then revert the code.
So for finding queries you have to follow these steps
1- Now go to cake folder and find this path cake\libs\model\datasources\dbo\dbo_mysql.php
2- find the function _execute. This function is responsible for all the queries what cakephp execute from its functions.
3- debug the $sql variable like
function _execute($sql) {
echo $sql;
return mysql_query($sql, $this->connection);
}
4- die the code after the cakephp background retrieval functions. like
$referral = $this->find('first', array(
'conditions' => array('Referral.id' => $id)
));
die();
5- If this is ajax call for that you can view the queries in firebug.
Note: The last displayed query will be your desire query before die

Resources