Jump to content

Creating Comments via API


Soma
 Share

Recommended Posts

May someone else finds this helpful.

I wanted to create comments (using built-in comments fieldtype module) via API, as I needed this is for an easy migration from an existing site. I figured following does the job:

<?php

// get the page that you want to add comment(s), contains a "comment" fieldtype
$p = $wire->pages->get("/guestbook/");

// create new Comment object
$c = new Comment();

// fill the object with values
$c->text = "Hello World!";
$c->cite = "John Average";
$c->created = time(); // timestamp, if you got to migrate a existing datetime you can convert using strtotime("2011-04-09 15:14:51")
$c->email = "john@average.com";
$c->ip = "..."; // not needed (only for akismet)
$c->user_agent = "...";  // not needed (only for akismet)
$c->created_users_id = "..."; // not needed, automaticly set by pw

// set status (Spam = -2; Pending = 0;  Approved = 1; )
$c->status = 1;

// add new comment object to the page "mycomments" field	
$p->mycomments->add = $c;

// save page
$p->save();

?>
  • Like 6
Link to comment
Share on other sites

Thanks, good post! I think others will definitely find this helpful.

Since you are migrating from another site. If you wanted to retain the dates of the original comments, converting from their string format, you could do this:

$c->created = strtotime("2011-04-09 15:14:51"); 

Also, I think you can probably skip setting the ip and user_agent, unless you've got that info you want to keep from your previous comments system. Those are used primarily by Akismet and other spam-detection services, and aren't really needed in your case.

Lastly, you can skip setting the created_users_id, because PW will set that automatically according to whoever is logged in when the comment is saved.

Thanks,

Ryan

Link to comment
Share on other sites

Thanks Ryan for the additional infos.

Yes, I also used strtotime to convert the dates to a timestamp in my case.

You're right, ip, use_agent and created_users_id aren't needed, just wanted to list them here for completion.

BTW: I tried to change a comments text from within the page in the backend, and it doesn't save it. Is that a bug or intetional.

Link to comment
Share on other sites

  • 1 month later...

Hi,

I am trying to add comments for my site using my own custom form and the API. I was unable to create the form I desired using the inbuilt comment form and further more I only want commenting to be available to registered users. As such the cite and email fields are not so important to me and can be hidden and pre-populated. Below is the code I have been trying to get to work but so far I cannot get it to save the comments to the system.

<?php

foreach ($page->comments as $comment) {

if ($comment->status < 1) continue; // skip unapproved or spam comments
$cite = $users->get($comment->created_users_id)->name; // make sure output is entity encoded
$text = htmlentities($comment->text);
$date = date('m/d/y g:ia', $comment->created); // format the date

echo "<div class='comment'>";
echo 	"<div class='comment-cite'><b>$cite</b> $date</div>";
echo 	"<div class='comment-body'>{$text}</div>";
echo "</div>";

}

if ($user->isLoggedin()) {

// Process submitted comments
if ($input->post->submit) {

	$c = new Comment();
	$c->text = $sanitizer->textarea($input->post['text']);
	$c->cite = $sanitizer->name($input->post['name']);
	$c->created = time();
	$c->email = $sanitizer->email($input->post['email']);
	$c->user_agent = $_SERVER['HTTP_USER_AGENT']; 
	$c->ip = $_SERVER['REMOTE_ADDR'];
	$c->created_users_id = $user->id;
	$c->sort = count($page->comments)+1;

	// set status (Spam = -2; Pending = 0;  Approved = 1; )
	$c->status = 1;

	// add new comment object to the page "comments" field	
	$page->comments->add($c);
	$page->save('comments');

}

?>			
<div class="comments-add">
	<form action="./" method="post">
		<input type='hidden' name='cite' value='<?=$user->name?>' />
		<input type='hidden' name='email' value='<?=$user->email?>' />
		<input type='hidden' name='page_id' value='<?=$page->id?>' />
		<textarea name="text" placeholder="Add a comment"></textarea>
		<input type="submit" name="submit" value="Add" />
	</form>
</div>
<?php

} else {

echo "<div class='comments-add'>";
echo "<p>You need to be <a class='login-link' href='/login/?ref={$page->url}'>logged in</a> to add a comment</p>";
echo "</div>";

}

?>

Any recommendation on where I am going wrong would be appreciated.

Thanks,

Stephen

Link to comment
Share on other sites

What error message are you getting? If not getting an intelligible error, edit your /site/config.php and find the line that says $config->debug = false; and set it to true.

The only thing I can think of in looking at the code you posted is that you might need to add a $page->setOutputFormatting(false) before your $page->save(). But if that's not it, I think we need more details on the error message.

Link to comment
Share on other sites

That's the odd thing - I don't get any error messages, even with debug on. I tried your suggestion about hiding ouput before save but it had no effect. Additionally I'm running the latest 2.1 and both the methods [tt]$page->comments->add()[/tt] and [tt]$page->save()[/tt] return true.

Stephen

Link to comment
Share on other sites

Just want to clarify that it's not about hiding output, but about turning the formatting off. So your code would look something like this:

<?php
$page->setOutputFormatting(false);
$page->comments->add($c);
$page->save('comments');

$session->redirect("./"); 
// or $page->setOutputFormatting(true); 

Note that redirect at the end. It's not entirely necessary, but it's something that I like to do just so that I'm getting a fresh copy of everything and preventing the possibility of having the user hit reload and re-posting the same thing. If you don't do the redirect, then you'll want to turn outputFormatting back on again.

Also note that you'll want to do all of this before you've output anything. So that means moving your comment saving code up above the code that outputs comments, as well as above any header includes or the like. This is only necessary if you are using the redirect, but I think it's a good idea either way because the comment the user just submitted could then become part of the output.  

If you are finding the comment is not getting saved, try a couple things that might help us to narrow down what's happening. First thing is to temporarily change your $page->save('comments') to $page->save();

If that doesn't make any difference, try adding $page->trackChange('comments'); before the save(). This is stuff you shouldn't have to do, but I'm hoping it might help us to debug.

  • Like 1
Link to comment
Share on other sites

Thanks for your excellent help, Ryan. I tracked down the problem in the end - the user I was testing this with did not have an email set so the comment was not added.

Nevertheless, your feedback was really useful and I am refreshing the session as you described.

Thanks,

Stephen

Link to comment
Share on other sites

  • 1 year later...

Hello,

I was experimenting with comments manipulation through the API and found that saving modified comments works when you specify the field name when saving your page.

For example, the following does not work:

$page->of(false);
$page->comments->get(0)->status = -2;
$page->save();
 

But the following does:

$page->of(false);
$page->comments->get(0)->status = -2;

$page->save('comments');
 

Seems you need to specify the comments field name explicitly when saving the page.

  • Like 1
Link to comment
Share on other sites

  • 3 years later...

Hi,

Great script. I managed to create my own form to submit Comments. It's working great on my local dev server, however, when I put it online, I get a Class Comment Not Found for the line:

$c = new Comment();

Everything is configured the same way on both sides.

I added the comments field to the template.

What am I missing?

Link to comment
Share on other sites

1 hour ago, Xonox said:

Hi,

Great script. I managed to create my own form to submit Comments. It's working great on my local dev server, however, when I put it online, I get a Class Comment Not Found for the line:


$c = new Comment();

Everything is configured the same way on both sides.

I added the comments field to the template.

What am I missing?

Something to do with PHP namespaces

  • Like 1
Link to comment
Share on other sites

  • 9 months later...

Hello guys. Does anyone has a working example of showing comment listing and comment form via the API that would include the page rating and comments voting? For sure I could edit the FieldTypeComments to apply the new code, but I find it much easier to call the comments via API. Unless there are some reasons to astray from using the API and use the official rendering methode?

Link to comment
Share on other sites

Aside from the unfortunate fact that I completely misread your question (just read the post title, thought you were trying to create comments), depending on the DB scheme you've selected, which field you need to populate will change, but try something like this

$c = new Comment();
$c->text = 'This is a comment';
$c->email = 'asd@asd.com';
$c->cite = 'abdus';
$c->website = 'https://google.com';
$c->stars = 5;
$c->upvotes = 10;
$c->downvotes = 1;
// $c->parent_id = 0; // or another comment's id
// $c->status = Comment::statusApproved;
// $c->ip = '127.0.0.1';
// $c->user_agent = 'Chrome';
// $c->created_users_id = $users('admin')->id;

$page->of(false);
$page->comments->add($c);
$page->save('comments');

 

Link to comment
Share on other sites

5 hours ago, MilenKo said:

working example of showing comment listing and comment form via the API that would include the page rating and comments voting

For that:

<?php namespace ProcessWire;

$list = new Commentlist($page->comments, [
    'useVotes' => true,
    'useStars' => true,
  
    // other options
    'headline' => '', 	// '<h3>Comments</h3>',
    'commentHeader' => '', 	// 'Posted by {cite} on {created} {stars}',
    'dateFormat' => '', 	// 'm/d/y g:ia',
    'encoding' => 'UTF-8',
    'admin' => false, 	// shows unapproved comments if true
    'useGravatar' => '', 	// enable gravatar? if so, specify maximum rating: [ g | pg | r | x ] or blank = disable gravatar
    'useGravatarImageset' => 'mm',	// default gravatar imageset, specify: [ 404 | mm | identicon | monsterid | wavatar ]
    'usePermalink' => false, // @todo
    'upvoteFormat' => '↑{cnt}',
    'downvoteFormat' => '↓{cnt}',
    'depth' => 0,
    'replyLabel' => 'Reply',
]);

echo $list->render();

 

  • Thanks 1
Link to comment
Share on other sites

  • 3 years later...
  • 2 years later...

Hi! For some reason all my comments added through API get added in the pending state and I don't understand, has anyone had this issue?? Running this through a CLI to read a CSV. 

$found = $pages->findOne("name={$some_string}");

$found->of(false);
$c = new Comment;
$c->stars = $stars;
$c->text = "$title\n$text";
$c->created = strtotime("first day of $created");
$c->set('status', 1);
$c->status = 1;
$found->comments->add($c);
$found->save('comments');
$found->comments->each(function($item) use($found){
  echo print_r($item, true);
  $item->set('status', 1);
  $item->status = 1;
  $found->save('comments');
});
$found->save('comments');

It would seem it has something to do to do with being created in the same request?? I am able to run this in the Tracy console and it just works 😕

EDIT: Just notices that the $page->comments value is empty when I run this through the CLI and the status is 1!

EDIT2: I guess and empty CommentsArray is reasonable since there are not approved comments?

Ended up doing:
 

$query = wire('database')->prepare("UPDATE field_comments SET status = 1 WHERE pages_id = {$page->id}");
wire('database')->execute($query);

Am I doing something wrong when creating the Comment object? That it's status doesn't get saved when saving the comments field?

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...