processwire / processwire-issues

ProcessWire issue reports.
45 stars 2 forks source link

FieldTypeComments - comment from parent page #1577

Open mdnamarie opened 2 years ago

mdnamarie commented 2 years ago

Short description of the issue

I have been rendering on one parent page all children pages (parent page template: group/ children pages template: group-post). The children are using a system of comment from the FieldTypeComments module, that is displayed on the parent page. All setting seem to be ok (see Optional: Screenshots/Links that demonstrate the issue) but new comments added appear on the last child created.

Expected behavior

I have been working on a website that has groups, in each group members can post images, youtube video url or plain text that will create a new child to the group (group-post). For each child (group-post) users can also respond to someone else's post, hence those page children have the comment field from FieldTypeComments module. The pages having the group-post template aren't supposed to be accessed directly, only the page having the group template.

Actual behavior

When there are multiple comment forms relating to different pages all rendered on the same page, the comments get the page_id from the last form on the page instead of the actual page_id value from the comment form.

Optional: Screenshots/Links that demonstrate the issue

https://processwire.com/talk/topic/27169-fieldtypecomments-how-to-comment-from-parent-page/#comment-224273

Way of calling children from the group template:

<!-- //group template  -->
<?php
//get children (group-post template)
foreach ($page->children->find("sort=-created") as $post ){

    echo $post->title;

    echo "<p class='CommentHeader'>";
    $post->of(false);
    $numTotal = $post->comments->count();
    if($numTotal <= 1){
        echo "{$numTotal} comment";
    }else{
        echo "{$numTotal} comments";   
    }
    echo "</p>";

    echo $post->body;

    if($post->get('comments')->count()){
        $list = $post->comments->getCommentList([
            'className' => 'CommentListCustom',
        ]); 

        $list->setMarkup([
            'noticeMessage' => "<div id='{id}' class='uk-alert {class}'>{message}</div>",
            'noticeSuccessClass' => 'uk-alert-success',
            'noticeErrorClass' => 'uk-alert-danger',
            'list' => "<ul id='my-comments-list' class='{class}'>{comments}</ul>", 
            // and so on for any other $markup properties
        ]); 

        echo $list->render();
    }else{
        echo"<small><p style='text-align:center;'>No comment yet, be the first!</p></small>";
    }

    $form = $post->comments->getCommentForm([
        'className' => 'CommentFormCustom',
    ]);

    $formMarkup = "
    <form class='{form.class} discussions_message ' id='my-comment-form' action='{form.action}' method='{form.method}' {form.attrs}>
                <div class='avatar'>";

    if(count($user->images)){ //profile image for the user since I am not using gravatar
        $imgUrl = $user->images->last()->url;
    } else{ 
        $imgUrl = $user->url;
    } 
    $formMarkup .= "<img src='{$imgUrl}' data-src='{$imgUrl}'>";

    $formMarkup .= "
                </div> 

                <p class='{cite.wrap.class}'>
                    <label class='{label.class}'>
                        <span class='{label.span.class}'>{cite.label}</span> 
                        <textarea name='{cite.input.name}'  class='{cite.input.class}' required='required' value='{cite.input.value}' >{cite.input.value}</textarea>
                    </label>
                </p>

                <p class='{email.wrap.class}'>
                    <label class='{label.class}'>
                        <span class='{label.span.class}'>{email.label}</span> 
                        <textarea name='{email.input.name}' class='{email.input.class}' required='required' value='{email.input.value}' >{email.input.value}</textarea>

                    </label>
                </p>

                {if.website}
                <p class='{website.wrap.class}'>
                    <label class='{label.class}'>
                        <span class='{label.span.class}'>{website.label}</span> 
                        <input type='text' name='{website.input.name}' class='{website.input.class}' value='{website.input.value}' maxlength='255' />
                    </label>
                </p>
                {endif.website}

                {if.stars}
                <p class='{stars.wrap.class}' {stars.wrap.attrs}>
                    <label class='{label.class}'>
                        <span class='{label.span.class}'>{stars.label}</span> 
                        {stars.markup}  
                    </label>
                </p>
                {endif.stars}

                {if.honeypot}
                <p class='{honeypot.wrap.class}'>
                    <label>
                        <span>{honeypot.label}</span>
                        <input type='text' name='{honeypot.input.name}' value='{honeypot.input.value}' size='3' />
                    </label>
                </p>
                {endif.honeypot}

                <p class='{text.wrap.class}'>
                    <label class='{label.class}'>
                        <textarea style='border: 1.5px solid !important;' name='text' class='{text.input.class} my-comment my-new-comment' required='required' rows='{text.input.rows}' cols='{text.input.cols}'>{text.input.value}</textarea>
                    </label>
                </p>

                {if.notify}
                <p class='{notify.wrap.class}'>
                    <label class='{notify.label.class}'>
                        <span class='{notify.label.span.class}'>{notify.label}</span>
                    </label> 
                    <label class='{notify.input.label.class}'>
                        <input class='{notify.input.class}' type='radio' name='{notify.input.name}' checked='checked' value='{notify.input.off.value}' {notify.input.off.checked}/> 
                        {notify.input.off.label}
                    </label>    

                    {if.notify.replies}
                    <label class='{notify.input.label.class}'>
                        <input class='{notify.input.class}' type='radio' name='{notify.input.name}' value='{notify.input.replies.value}' {notify.input.replies.checked}/> 
                        {notify.input.replies.label}
                    </label>    
                    {endif.notify.replies}

                    {if.notify.all}
                    <label class='{notify.input.label.class}'>
                        <input class='{notify.input.class}' type='radio' name='{notify.input.name}' value='{notify.input.all.value}' {notify.input.all.checked}/> 
                        {notify.input.all.label}
                    </label>    
                    {endif.notify.all}
                </p>    
                {endif.notify}

                <p class='{submit.wrap.class}'>
                    <button type='submit' class='{submit.input.class} button' name='{submit.input.name}' value='{submit.input.value}'>Reply</button>
                    {form.hidden.inputs}
                </p>
            </form>
  ";

    $form->markup('form', $formMarkup);
    $form->labels('submit', 'Submit Feedback');
    $form->labels('notify', 'Email Me');

    // form notifications
    $form->markup('notification', "<div class='uk-alert {class}'>{message}</div>");
    $form->classes('success', 'uk-alert-success');
    $form->classes('pending', 'uk-alert-warning');
    $form->classes('error', 'uk-alert-danger');

    echo $form->render();

}
?>

Comment forms with their page ID being set in the hidden page_id field of the comment form:

Capture d’écran 2022-05-27 à 23 15 46 Capture d’écran 2022-05-27 à 23 16 15 Capture d’écran 2022-05-27 à 23 16 44

renderSuccess function redirect url as it should : http://localhost:888/groups/group/group-post-id-1218/?comment_success=1&comment_approved=1#Comment68

acutal behavior:

Capture d’écran 2022-05-28 à 11 16 09

Steps to reproduce the issue

  1. Step 1: create a parent page (template group)
  2. Step 2: add at least 2 children (template goup-post) having a comment field from FieldTypeComments
  3. Step 3: comment the oldest child (the comment should appear on the oldest child but appear on the newest child)

Setup/Environment

Toutouwai commented 2 years ago

A simplified way to reproduce this issue:

foreach($page->children as $child) {
    echo $child->comments->renderAll();
}

This results in duplicate ID attributes in the page source. And when any one comment form is submitted all the forms get processed and the submitted comment usually isn't connected to the correct child page. Could the hidden page_id field be used to correctly connect the submitted comment to its page?