Textpattern CMS support forum
You are not logged in. Register | Login | Help
- Topics: Active | Unanswered
Pages: 1
#1 2011-03-28 16:16:16
- frickinmuck
- Member
- Registered: 2008-05-01
- Posts: 118
Adding fields to comment form
I want to add a couple of text input fields to my comment form – anyone have any advice on doing that? I’m by no means a SQL wiz, but I assume it would involve adding those fields to the db, etc. and perhaps modifying the comment admin page to show those fields. Would it be do-able, and if so, what’s involved? I’m actually quite amazed there isn’t an instruction or plugin already available for this, but I Googled like crazy to no avail.
Last edited by frickinmuck (2011-03-28 16:17:24)
The AI does not hate you, nor does it love you, but you are made out of atoms which it can use for something else.
Offline
Re: Adding fields to comment form
Have a look at mem_form
and mem_public_article
.
Basically, you can have a public side form to post anything to any table in the database (including custom tables and fields). It means you won’t be extending the comment form as such, but creating your own comment form with whatever fields you want.
Offline
#3 2011-03-29 15:08:46
- frickinmuck
- Member
- Registered: 2008-05-01
- Posts: 118
Re: Adding fields to comment form
Thank you so much for the suggestion. I’ll let you know how it works out!
The AI does not hate you, nor does it love you, but you are made out of atoms which it can use for something else.
Offline
Re: Adding fields to comment form
Is there some easy, or at least not a super hard, way to add a new field to current comment form? I wouldn’t like to use mem_form or other plugins, just the standard comment form with some new fields. I’m thinking of implementing the Rich Snippets (more from here) thing so that users could rate what is presented in the article. Email and URL fields are reserved to what they’re meant be used, so I can’t use them in this project.
Offline
Re: Adding fields to comment form
kuopassa wrote:
Is there some easy, or at least not a super hard, way to add a new field to current comment form?
Define easy ;-) You could pretty much as-well write a whole new comment saving system (it’s not that much code), or use mem_form. If you really want to add new fields to the comment form, it’s relatively possible, but you will have to write PHP.
It all wrangles around single callback. Textpattern’s comment system provides a callback point named comment.save
, by hooking to that it’s potentially possible to save extra information every time a comment is saved, which would allow adding extra fields to the comment form.
Now the first challenge comes in form of saving the data; it’s not exactly like just pressing CMD+S. The callback is ran before saving, which means you can’t save the data with the actual comment (not without replicating the whole saving process). You will have to use different database table and then link/join the rows together, which then introduces the second problem; identifying the comments.
As the saving is done after the callback, you have nothing to use to detect comments. Only data you can work with is what is sent, a comment’s ID is still unknown. You could obviously use email and username or IP to detect the user. As it is rating IP could be reasonable option.
Still chewing all that, I’m going to give small example of saving new comment data:
/**
Hook xxx_user_rating function to comment.save event
*/
register_callback('xxx_user_rating','comment.save');
/**
Handles saving of the new data. We expect that there is database table
called 'xxx_user_rating' with 4 columns named id, article, ip and rating.
Following SQL could be used to create such table:
CREATE TABLE xxx_user_rating (
`id` int(6) unsigned NOT NULL AUTO_INCREMENT,
`article` int(11) NOT NULL DEFAULT '0',
`ip` varchar(100) NOT NULL DEFAULT '',
`rating` tinyint(2) unsigned NOT NULL DEFAULT '5',
PRIMARY KEY (`id`),
KEY `parentid` (`article`)
) CHARSET=utf8 PACK_KEYS=1;
*/
function xxx_user_rating() {
/*
Get the sent rating value from 'xxx_user_rating' field,
and make sure it contains an integer.
*/
$rating = assert_int(ps('xxx_user_rating'));
/*
Make sure that the rating is even value
between 1 to 10. If not, default to five.
*/
if(!in_array($rating, range(1,10)))
$rating = 5;
/*
Get user's IP address
*/
$ip = doSlash(remote_addr());
/*
Get article ID
*/
$article = assert_int(ps('parentid'));
/*
If rating already exists end here.
Look for article's ID and user's IP.
*/
if(
safe_row(
'id',
'xxx_user_rating',
"ip='$ip' and article='$article' LIMIT 0, 1"
)
)
return;
/*
Insert a new rating.
*/
safe_insert(
'xxx_user_rating',
"ip='$ip', article='$article', rating='$rating'"
);
}
Note that above is an example. I haven’t tested it, and might not work. The code expects that there is a database table called ‘xxx_user_rating’ for storing ratings. There is a SQL snippet in one of the comments for creating the table. To load the above code, save it as a plugin. One of the easiest methods of doing so is to use ied_plugin_composer.
If you are using anti-spam plugins that block comments form saving (rah_comment_spam etc), you will need to add comment evaluator check at the top of the function as anti-spam plugins and others are loaded on the same callback. I.e. something like:
/* If set as 'reload', end here */
$evaluator =& get_comment_evaluator();
if($evaluator->get_result() == RELOAD)
return;
When all that rating saving is implemented, also now you will have to somehow implement showing of the ratings. You would have to write a code that counts averages, pulls and formats the ratings, and all that.
To display the ratings in the comments you could use smd_query, or something else (i.e. own, bundled, more faster queries). You will need the comments IP (which is stored inside the database with a every comment) and article’s ID for pulling the ratings to comments.
Now, if you want to administrator the ratings, then there is also left the administration side of things; deleting and updating values. As the ratings are stored in separate table, they won’t be deleted with comments (which can be good thing too, depending on what you want).
Easy? Maybe not. Possible? Kinda. Secure and integrated to the commenting system? Yes, as asked. Hope that all helps somewhat.
Last edited by Gocom (2011-09-11 17:54:52)
Offline
Re: Adding fields to comment form
Thanks for guiding through this, Gocom. Seems like I’ve just managed to crack this and by this I don’t mean my nerves, but the saving of new field value to database via comment form. The rating system is meant to be so that same IP address should be allowed to post again and again if the user wants, so this code example below allows that. Also this code doesn’t use all the Textpattern functions that you wrote, as they didn’t let any comments to go through (was a problem with some function in lib/txplib_misc.php). My code example is very primitive, so it needs some fine tuning. I’ll do that later. Fun things. :-)
register_callback('xxx_user_rating','comment.save');
function xxx_user_rating() {
$rating = is_numeric(ps('rating'));
if(!in_array($rating, range(1,10)))
$rating = '5';
$ip = doSlash(remote_addr());
$article = assert_int(ps('parentid'));
safe_insert(
'xxx_user_rating',
"ip='$ip', article='$article', rating='$rating'"
);
}
To carry the rating number through comment preview phase, I just used this method:
<input type="text" name="rating" size="5" value="<txp:php> echo $_POST["rating"]; </txp:php>" maxlength="2" />
Last edited by kuopassa (2011-09-12 01:25:14)
Offline
Re: Adding fields to comment form
kuopassa wrote:
My code example is very primitive, so it needs some fine tuning.
That code won’t work. Ratings aren’t saved as $rating
is set as bool in $rating = is_numeric(ps('rating'));
. I.e. do:
$rating = (int) ps('rating');
To carry the rating number through comment preview phase, I just used this method:
If you take the value directly from POST, then please escape it to prevent XSS attacks. See Textpattern’s ps()
function, and hInput()
or htmlspecialchars()
. I.e.
<txp:php>
echo hInput('rating', ps('rating'));
</txp:php>
Consider prefixing the field name to avoid conflicts as per namespace guidelines.
The rating system is meant to be so that same IP address should be allowed to post again and again if the user wants, so this code example below allows that.
You won’t be able to show the ratings in comments, tho. Won’t be able to reliably know which rating belongs to which comment, unless you always pick the newest one of the ratings. Even then there is a problem with the fact that IPs are not unique to single user.
Last edited by Gocom (2011-09-12 07:12:36)
Offline
Re: Adding fields to comment form
Thanks again, Gocom. I’ll continue to test this later today and will try to implement your advices to the code. I see in database table txp_discuss
that each comment has unique date/time stamp, so couldn’t that information be injected also to xxx_user_rating
’s comments? If both tables have the identical time of publishing the comment, wouldn’t it make possible to later identify which comment belongs to which rating?
Offline
Re: Adding fields to comment form
kuopassa wrote:
I see in database table
txp_discuss
that each comment has unique date/time stamp, so couldn’t that information be injected also toxxx_user_rating
’s comments?
Unfortunately no. The rating is saved before the comment, which means that you won’t know the time when the comment will be (future tense) published. If it was possible, you should use the comment_id instead of the time, but unfortunately it isn’t.
If both tables have the identical time of publishing the comment, wouldn’t it make possible to later identify which comment belongs to which rating?
Each query gets executed independently; different times. The rows might not end up with same second-precise publishing time.
Last edited by Gocom (2011-09-12 17:02:07)
Offline
Pages: 1