Drupal adding rows in comment storage - Where to edit 'INSERT' query? - php

I edited the 'comment' table in my Drupal MySQL database to add two rows. This is because I have a page that takes in a URL parameter, so while there is one page, I need to distinguish between the values of that parameter for comments. I'm having trouble editing my comment.module to edit the MySQL query. I can't find any kind of 'INSERT into...' query anywhere, not just in that file. I've looked through everything in the comment module folder.
What appears to be what affects the database insertion is the comment_publish_action() function in comment.module but I'm still running into some problems regarding the added columns, as they don't have default values.
Here's that function, 'typenode' and 'idofnode' are the added columns with test values:
function comment_publish_action($comment, $context = array()) {
if (isset($comment->subject)) {
$subject = $comment->subject;
$comment->status = COMMENT_PUBLISHED;
}
else {
$cid = $context['cid'];
$subject = db_query('SELECT subject FROM {comment} WHERE cid = :cid', array(':cid' => $cid))->fetchField();
db_update('comment')
->fields(array(
'status' => COMMENT_PUBLISHED,
'typenode' => 'player',
'idofnode' => 1239
))
->condition('cid', $cid)
->execute();
}
watchdog('action', 'Published comment %subject.', array('%subject' => $subject));
}

Edit comment.module is not good idea. During next core updates all changes will be lost. Better to create a custom module and implement some hooks there.
There is function comment_save($comment) which perform steps to insert / update new comment. In this function you can find a line drupal_write_record('comment', $comment); which do insert or update of db table 'comment' (dependence on logic). But before this line there is hook module_invoke_all('comment_presave', $comment); which allows you to modify $comment object before it will be store in database. This is good way to go - implement this hook in custom module and do modifications there.
function custom_module_comment_presave($comment) {
//add rows info here
}

Related

creating a variable shortcode based on user input that returns (prechosen) variables Wordpress

I need to update values in all posts of a wordpress installation on a regular base. I was gooing to use shortcodes to insert the request into the wordpress post. Then use a custom functions.php that holds all the variables that need to be updated from time to time.
I got it working. Somehow but not the way I intended to use it. I'm a total beginner. Please consider this when answering my questions.
I want to have a function that reads what comes after honda_ and displays the correct value in wordpress without having to create a separate shortcode for each variable.
When entering [honda_link] wordpress should display the value from honda_link. When entering [honda_longlink] the value from honda_longlink variable should get displayed. I don't want to create a shortcode for each value.
I came up with this as a working solution...
// Honda
function honda() {
$honda_link = 'www.honda.com';
$honda_longlink = 'http://www.honda.com';
$honda_free = 'Free';
$honda_new = '23.688 $';
$honda_mileage = '00';
return $honda_link;
}
add_shortcode('neu', 'honda_link');
I tried some approaches by using an array but it ultimately failed all the time. I also tried it with if statements but wasn't able to get the right value displayed.
Someone willing to help a noob? I think I need to see a working example in order to understand it. The code snippets I have been looking at (that do something similiar but not the same I want to achieve) did confuse me more than they helped me.
I came up with this / Which works in a way but... This isn't very comfortable to use.
add_shortcode('HONDA','HONDA_TEST');
function HONDA_TEST($atts = array(), $content = null, $tag){
shortcode_atts(array(
'var1' => 'default var1',
'var2' => false,
'var3' => false,
'var4' => false
), $atts);
if ($atts['var2'])
return 'honda2';
else if ($atts['var3'])
return 'honda3';
else if ($atts['var4'])
return 'honda4';
else
return 'honda1';
}
So now when using:
[HONDA var1="novalue"][/HONDA]
[HONDA var2="novalue"][/HONDA]
[HONDA var3="novalue"][/HONDA]
[HONDA var4="novalue"][/HONDA]
it shows:
honda1
honda2
honda3
honda4
and so on.
Is there a better way to achieve the intended goal from post #1 ? Any way I could import the $variables from 1st post in bulk for example?
I don't have a working WP setup right now to test, but could you try this:
add_shortcode('HONDA','HONDA_TEST');
function HONDA_TEST($atts = array(), $content = null, $tag){
$atts = shortcode_atts(array(
'model' => 1,
), $atts);
$myHondas = [1 => 'honda1', 'honda2', 'honda3'];
return isset($myHondas[$atts['model']]) ? $myHondas[$atts['model']] : 'unknown model id';
}
And use it with [HONDA model="1"], [HONDA model="2"]

Update two models using yii x-editable

So, I'm using this extension: x-editable for yii.
And I'm currently trying to update two models in update() function.
I have two models:
Realisasi.php
RealisasiDeadline.php.
So when a cell is updated on table Realisasi.php (one value in column t1701 in this case), I want the function to update the corresponding value in column t1701 of table RealisasiDeadline, using column no as the foreign key.
Since I haven't found any example on Google, I made it up myself:
public function actionSimpanEdit($kode) {
Yii::import('editable.EditableSaver');
$es = new EditableSaver($_GET['model']); // 'modelName' is classname of model to be updated
$es->update();
$es2 = RealisasiDeadline::model()->findByPk($kode);//this is where I'm stuck
$es2['t1701'] = '1991-11-19';//this too
$es->update();//and this
}
This is the view.php:
array(
'name' => 't1701',
'value' => 'CHtml::value($data,"hubtarget.t1701")=== "0"?"Target Nol":$data->t1701',
'header' => 'Bkl Selatan',
'class' => 'editable.EditableColumn',
'editable' => array(
'url' => $this->createUrl('simpanEdit', array('model' => 'Realisasi', 'kode'=>'$data->no')),
)
),
What have I missed? Is it possible at all to do? If not, is there another solution?
UPDATE
It's not showing any error. But the value in table RealisasiDeadline doesn't change, only the one in Realisasi does.
Added some comments to original function so you can improve upon it. Biggest issue with this code is that looking at it I have no idea what it does.
public function actionSimpanEdit($kode) {
Yii::import('editable.EditableSaver'); // Should be at the top of the file
// For the love of god use descriptive variable names
$es = new EditableSaver($_GET['model']); // Would prefer to have model as actions argument
$es->update();
$es2 = RealisasiDeadline::model()->findByPk($kode); // no idea what this model is responsible for
$es2['t1701'] = '1991-11-19'; // no idea what attribute t1701 is, use descriptive names
$es->update();
}
I have refactored it a bit. Still have no idea what it does ;/
public function actionSimpanEdit($id, $model) {
$editableSaver = new EditableSaver($model);
$editableSaver->update();
$deadline = RealisasiDeadline::model()->findByPk($id);
if($deadline instanceof RealisasiDeadline) {
$deadline->t1701 = '1991-11-19';
if(!$deadline->update()) {
// something went wrong
}
} else {
// not found
}
}
Going back to your problem. It is probably caused by RealisasiDeadline model being not found or some behavior or event preventing it from update.

CakePHP how to add data from another field of a related model

This is one of my first applications out of tutorials so I don't know how to express my issue well.
Well I have these 2 tables:
User ( id, code )
Hours ( id, user_id, created)
I want to know how I can add an entry to the Hours table using the user_code.
I tried to grab the data of the User table with the code value and then findBy and pass for the patchEntity but it did not work.
I don't have a whole lot of information to work with, but I'll give it a go.
I want to know how I can add an entry to the Hours table using the
user_code
You mention using patchEntity, so that's updating information that's already there. Assuming user_code is the 'code' column you're talking about there, first find the user by his code:
$users_tbl = TableRegistry::get('Users');
// find the user
$user = $users_tbl->findByCode($user_code)->first();
if ($user) {
// replace '$this->request->data() with whatever patch data you wanted
$users_tbl->patchEntity($user, $this->request->data(), [
'associated' => ['Hours']
]
if ($users_tbl->save($user)) {
// success!
} else {
// error!
}
} else {
// error!
}
It will also depend on how you have the data you passed in (where my '$this->request->data() is, or whatever your array might be) - it needs to match the right column names and be in the correct format listed here.
However, this is updating the data. Just adding the data, you can load the hours table and add a new entry with the user_id acquired from the user search:
$hours_tbl = TableRegistry::get('Hours');
$hours = $hours_tbl->newEntity([
'user_id' => $user->id // $user populated from same method earlier
]);
/* assumed 'id' was autoincrementing and 'created' was populated
through Timestamp behavior */
if ($hours_tbl->save($hours)) {
// yay!
} else {
// boo
}

Data concurrency management in CakePHP - Behavior / Controller / Model?

In order to manage concurrency - that is ensuring that data being saved to the database is not stale or already edited by some other user - in my CakePHP application I am using the modified attribute in my edit functions. Below is a snippet of the code that is in my controller.
$this->MyModel->recursive = -1;
$event = $this->MyModel->findById($id);
$requestTimeStamp = new DateTime($this->request->data['MyModel']['modified']);
$dbTimeStamp = new DateTime($event['MyModel']['modified']);
if ($requestTimeStamp < $dbTimeStamp) {
$response = array(
'success' => false,
'id' => $id,
'message' => 'A concurrency error occurred while trying to save. Please try again');
echo json_encode($response);
exit;
} else {
//... continue processing
}
This code works fine - but as I try to optimize it across my application I am trying to figure out where best to place it. Is it best placed in my AppModel class or is it better to create a Behavior for the same or is it just best left in the controller? I suppose that an ideal option would consider performance and minimize the amount of class loading overhead as well as database access overhead.
Has anyone come across / solved this problem before? Thoughts / suggestions appreciated.
So I solved this by making concurrency check a part of my AppModel->beforeSave() method. Below is the code for reference of others
/*
* Incorporated concurrency check in the beforeSave callback method to ensure that data is not stale before user saves.
* The function checks if the model has a `modified` field, before it proceeds. If the model does not have such a method
* then concurrency does not apply to this data structure. Upon proceeding, the method checks to see if the value of modified
* data is the same in the database as well as the request that invokes this method. If they are not same then the save is
* aborted
* This method requires the view or controller to pass a variable called data[ModelName][modified].
* This variable must contain the value of the modified field when the record was read and it must be passed back as such.
* I usually set a hidden form field in my view like below -
* <input type="hidden" name="data[Model][modified]" value="<?php echo $model['modifed']; ?>" />
*/
public function beforeSave($options = array()) {
if ($this->hasField('modified') && isset($this->data[$this->name]['id']) && isset($this->data[$this->name]['modified'])) {
CakeLog::debug('AppModel: beforeSave - inside concurrency check');
CakeLog::debug($this->data);
$this->recursive = -1;
// run a select statement to ensure the modified date in the database has not changed. If it has changed then
// the below find query will return 0 rows
$row = $this->find('first', array(
'fields' => array(
'id', 'modified'
),
'conditions' => array(
'id' => $this->data[$this->name]['id'],
'modified' => $this->data[$this->name]['modified']
)
));
// if no row is returned then error out and return - basically a concurrency error has occurred
if (!$row) {
CakeLog::error($this->name.':Concurrency error - [row-id:'.$this->data[$this->name]['id'].']');
return false;
}
// if a row was retrned then there is no concurrency error, so proceed but change the modified date
// to current timestamp to reflect accuracy
$this->data[$this->name]['modified'] = date('Y-m-d H:i:s');
return true;
}
}

Codeigniter active record query cached - look for old table name instead of new one

I have project with 3 application's sharing one codeigniter installation. It was working excellent until I changed name of mysql table, and changed query to reflect new changes to the database. Now it looks like my insert query is cached, and trying to insert value into old table (which doesn't exist anymore). This is what I've tried so far:
CI:
$this->db->cache_delete_all()
mysql:
RESET QUERY CACHE;
In config/database.php:
$db['default']['db_debug'] = TRUE;
$db['default']['cache_on'] = FALSE;
When db_debug configuration is set to TRUE it gives 500 error, when FALSE, I was able to catch error and it turn's out it's trying to insert into old table that doesn't exist anymore. I don't get how is this possible, I've even searched my complete project and can't find old table name anywhere in my project, also CI cache folders are empty. Any help would be appreciated.
EDIT: My insert code:
if($this->db->insert('booking_calendar', $data))
{
$booking_id = $this->db->insert_id();
$this->load->helper('string');
$order_id = strtoupper(random_string('alnum', 6)) . $booking_id;
$data = array(
'id' => $order_id,
'booking_calendar_id' => $booking_id,
'status' => 'PAYMENT_PENDING'
);
if($this->db->insert('bookings', $data))
{
$this->notifications->add($MYSELF['id'], 'Court successfully booked.');
return $order_id;
}
$this->notifications->add($MYSELF['id'], 'Court booking failed.', 'warning');
return false;
}
else
{
log_message('ERROR', 'Insert booking_calendar failed. ' . print_r($this->db->_error_message(), true));
}
And this is the output in my log:
ERROR - 2013-09-23 20:05:13 --> Insert booking_calendar failed. Table 'tennis.courts_calendar' doesn't exist
Notifications is custom class which just insert one row in "notifications" table.
I found answer to my problem, I had ON BEFORE INSERT/UPDATE triggers on my table, and when I changed it's name it turns out that inserting on the same table with new name was still triggering old table name instead of new one. So I just updated triggers and now it's working. Hope this will save time for someone else, because it took me a while even if it's looking trivial from this point of view now.

Categories