Soma Posted August 18, 2011 Share Posted August 18, 2011 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(); ?> 6 Link to comment Share on other sites More sharing options...
ryan Posted August 18, 2011 Share Posted August 18, 2011 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 More sharing options...
Soma Posted August 18, 2011 Author Share Posted August 18, 2011 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 More sharing options...
ffub Posted September 30, 2011 Share Posted September 30, 2011 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 More sharing options...
ryan Posted September 30, 2011 Share Posted September 30, 2011 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 More sharing options...
ffub Posted September 30, 2011 Share Posted September 30, 2011 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 More sharing options...
ryan Posted September 30, 2011 Share Posted September 30, 2011 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. 1 Link to comment Share on other sites More sharing options...
ffub Posted October 1, 2011 Share Posted October 1, 2011 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 More sharing options...
Valery Posted May 28, 2013 Share Posted May 28, 2013 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. 1 Link to comment Share on other sites More sharing options...
Xonox Posted December 21, 2016 Share Posted December 21, 2016 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 More sharing options...
elabx Posted December 21, 2016 Share Posted December 21, 2016 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? 1 Link to comment Share on other sites More sharing options...
Xonox Posted December 21, 2016 Share Posted December 21, 2016 7 minutes ago, elabx said: Something to do with PHP namespaces? Solved it!!!! It isn't namespaces, thanks for the suggestion! It was the freaking cache!!!! It gets me everytime! Emptied the cache and it's working 2 Link to comment Share on other sites More sharing options...
MilenKo Posted September 30, 2017 Share Posted September 30, 2017 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 More sharing options...
abdus Posted September 30, 2017 Share Posted September 30, 2017 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 More sharing options...
abdus Posted September 30, 2017 Share Posted September 30, 2017 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(); 1 Link to comment Share on other sites More sharing options...
Schwab Posted October 4, 2020 Share Posted October 4, 2020 deleted Link to comment Share on other sites More sharing options...
elabx Posted January 12, 2023 Share Posted January 12, 2023 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 More sharing options...
adrian Posted January 12, 2023 Share Posted January 12, 2023 @elabx - I found the same as you that the only way was to do a direct SQL update. Just looking and this problem seems to be around forever based on this really old code: https://github.com/adrianbj/ProcessMigrator/blob/master/ProcessMigrator.module#L1707-L1714 1 Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now