WordPress.org

Ready to get started?Download WordPress

Forums

[resolved] [closed] Remove text field from comment form (50 posts)

  1. edow
    Member
    Posted 4 months ago #

    I found out the problem with the avatars. All I had to do was to change $comment->comment_author_email to $like->comment_author_email and $unlike->comment_author_email.

    :)

    To return a value that can be assigned to a local variable for use elsewhere on the page looks like the best solution. I have to figure this out, because I'm a noob with this. Thanks for giving me a clue.

  2. edow
    Member
    Posted 4 months ago #

    Now I see there's only another little problem: if another user with the same name but another email address give a like/unlike it says:

    Duplicate comment detected; it looks as you already said that!

    Is it possible to change this to something like:

    Duplicate comment or not an unique username detected! If so, choose another username.

  3. bcworkz
    Member
    Posted 4 months ago #

    Another good catch! So obvious now, yet no one could see it for so long. Even if you are weak with writing code, you are becoming a master debugger :)

    Yes, we can change the duplicate message. It seemed better to alter the check to only check comments with the same email or skip the duplicate check entirely. Neither of these appear to be possible, so change the message it is. I'm suggesting a slightly different message in the code, feel free to change the message as you please.

    add_action( 'comment_duplicate_trigger', 'edow_dupe_msg' );
    function edow_dupe_msg() {
       wp_die('You either already voted or are voting using an existing username, please go back and pick a different username if you haven't yet voted.');
    }

    To wrap your code in a function that returns the score, it would look something like this:

    function edow_get_score() {
       //your code here
       return $score;
    }

    This goes on functions.php or a simple plugin.

    Then to use the function on your template, it must be inside the "Loop". You can use it in a couple of ways, placing the code where you want the score to appear:

    //single use
    echo edow_get_score();
    
    //mulitple use, first use
    echo $score = edow_get_score();
    //OR this equivalent code
    $score = edow_get_score();
    echo $score;
    
    //additional uses farther down the template
    echo $score;

    If you also need the like and unlike counts, you will also need to compact the variables into an array inside the function, then extract the individual values on the template after the function call.

  4. edow
    Member
    Posted 4 months ago #

    Thanks! The message function is working great.

    About the other function. This code displays the avatars correctly:

    function aigoo_get_score() {
       $comments = get_comments( array('post_id' => get_the_ID(),) );
    			$likes = array();
    			$unlikes = array();
    			foreach( $comments as $comment ) {
    				if('unlike' == $comment->comment_content ) $unlikes[] = $comment;
    					else $likes[] = $comment;
    			}
    	echo '<div class="upvoters" id="votes">';
    	echo '<span class="numberoflikes">('.count($likes).')</span>';
    	echo '<div class="upvoter-img">';
    	foreach( $likes as $like )
    		echo("<img src=\"".get_avatar_url(get_avatar( $like->comment_author_email, 40 ))."\" class=\"tooltip\" title=\"".$like->comment_author."\" width=\"40\" height=\"40\">");
    	echo '</div>';
    	echo '</div>';
    	echo '<div class="downvoters">';
    	echo '<span class="numberofunlikes">('.count($unlikes).')</span>';
    	echo '<div class="downvoter-img">';
    	foreach( $unlikes as $unlike )
    		echo("<img src=\"".get_avatar_url(get_avatar( $unlike->comment_author_email, 40 ))."\" class=\"tooltip\" title=\"".$unlike->comment_author."\" width=\"40\" height=\"40\">");
    	echo '</div>';
    	echo '</div>';
       return $score;
    }

    If I add the following code in the above code...

    $likescore=array(count($likes));
    $unlikescore=array(count($unlikes));

    ... and call it with:
    echo $likescore;

    ... then there is no like score displayed.

    So the avatars are working great. Only now the working score code isn't working anymore. I would like to use echo $likescore; and echo $unlikescore; to hold the like and unlike score, because then I can do (I think) the following to calculate the real score:

    $score = $likescore - $unlikescore;
    $totalvotes = $likescore + $unlikescore;

    After that I can style the output with CSS.

    So, the avatars are showing, but the score isn't displaying anymore.

  5. bcworkz
    Member
    Posted 4 months ago #

    Yes, no surprise there. I wasn't sure how you wanted to use the data. I picked one approach and guessed wrong. I mentioned another approach with arrays, but apparently didn't give you enough to go on. Here's more.

    Simply making something an array inside a function does not make it available outside the function. We coders say such variables are out of "scope". You can make them available by declaring them "global", but global variables are generally considered poor, sloppy, lazy coding by most coders. (WP uses them quite a bit though.) I personally try to avoid them if there's another way.

    There's another way. The problem is you can only return one value from a function. Fortunately, you can pass a single array containing many values, so you just need to put all the data you want into a single array. One way you could do this is:
    return array( count( $likes ), count( $unlikes ));
    instead of returning $score ($score isn't working because you used different code than I expected in the function, which is fine, I'll adapt)

    Another way is this:

    $likescore = count( $likes );
    $unlikescore = count( $unlikes );
    return compact('likescore', 'unlikescore');

    Either way, you call the function like so:
    $counts = aigoo_get_score();

    Depending on the return style, you use $counts differently. For the first style, you might do this:

    echo "Number of Likes: {$counts[0]}\n";
    echo "Number of Unlikes: {$counts[1]}\n";

    With the second style you could do this:

    echo "Number of Likes: {$counts['likescore']}\n";
    echo "Number of Unlikes: {$counts['unlikescore']}\n";

    OR this:

    extract( $counts );  //restores compacted variables
    echo "Number of Likes: $likescore\n";
    echo "Number of Unlikes: $unlikescore\n";

    Any of these work equally well. The choice of one way or another is partly personal preference and partly how you intend to use the returned data. The first way is easier to code, and sort of clear what's happening, but the code is not very readable.

    The second way takes more lines and is hard to follow if you do not understand compact() and extract(), but the resulting variables are much more readable. $counts[0] versus $likescore :)

    I hope that all makes sense and you can get working code out of it. If not, pick one of the methods and implement as best you can. Post your latest coding effort again and I'll get you straightened out. Good luck!

  6. edow
    Member
    Posted 4 months ago #

    Thanks a lot again! I'm away for the weekend, so I will test it monday. Can't wait to try it.

  7. edow
    Member
    Posted 4 months ago #

    I tried to following code in functions.php:

    function aigoo_get_score() {
       $comments = get_comments( array('post_id' => get_the_ID(),) );
    			$likes = array();
    			$unlikes = array();
    			foreach( $comments as $comment ) {
    				if('unlike' == $comment->comment_content ) $unlikes[] = $comment;
    					else $likes[] = $comment;
    			}
    	echo '<div class="upvoters" id="votes">';
    	echo '<span class="numberoflikes">('.count($likes).')</span>';
    	echo '<div class="upvoter-img">';
    	foreach( $likes as $like )
    		echo("<img src=\"".get_avatar_url(get_avatar( $like->comment_author_email, 40 ))."\" class=\"tooltip\" title=\"".$like->comment_author."\" width=\"40\" height=\"40\">");
    	echo '</div>';
    	echo '</div>';
    	echo '<div class="downvoters">';
    	echo '<span class="numberofunlikes">('.count($unlikes).')</span>';
    	echo '<div class="downvoter-img">';
    	foreach( $unlikes as $unlike )
    		echo("<img src=\"".get_avatar_url(get_avatar( $unlike->comment_author_email, 40 ))."\" class=\"tooltip\" title=\"".$unlike->comment_author."\" width=\"40\" height=\"40\">");
    	echo '</div>';
    	echo '</div>';
        $likescore = count( $likes );
    	$unlikescore = count( $unlikes );
    	return compact('likescore', 'unlikescore');
    }

    and this code in single.php:

    extract( $counts );  //restores compacted variables
    echo "Number of Likes: $likescore\n";
    echo "Number of Unlikes: $unlikescore\n";

    But then I get no scores. Also, under the avatars now is shown the word "array". Not sure why it isn't working for me.

    I also use this line of code to count the likes and unlikes:
    $totalvotes = count($likes) + count($unlikes);
    Is there a way I can use this again with the new code?

    I'll try it again, but for now it isn't working.

  8. edow
    Member
    Posted 4 months ago #

    The word "array" is now gone, because I forgot to use $counts = aigoo_get_score();, but the scores are not showing yet.

  9. bcworkz
    Member
    Posted 4 months ago #

    I'll answer the easy question first. You cannot use $totalvotes = count($likes) + count($unlikes); in this new scheme because the $likes and $unlikes arrays are of local scope to the function aigoo_get_score(). The arrays are thus out of scope to any code on single.php. What you will want to do instead is use this:
    $totalvotes = $likescore + $unlikescore;

    (at the risk of confusing the issue, alternately, you could use your original code line inside the function where the arrays are in scope. Then add 'totalvotes' to the compacted data at the end. You could then use $totalvotes anywhere after the function call.)

    I'm unsure why you are not seeing scores :(
    You are seeing the avatars where you call aigoo_get_score(), right?
    And the call to aigoo_get_score() and the extract() and echo lines are all on single.php and occur in the order listed herein, right?
    All the code is placed inside of a <?php ?> block, right?
    The call to aigoo_get_score() must be inside the "Loop".

    If all the above checks out, try putting the two echo lines inside the function declaration just above the return line. This is to test that the count() functions are working and that the issue is with the compact() and extract() functions, or that the reverse is the case. Either way it narrows down where to look for problems. This is basic debugging -- insert code somewhere so you can determine if the problem is before or after that inserted code. Keep changing this location and you will eventually zero in on the exact line where the error occurs.

    Once again, I'm at a loss for what may be the problem. I've retested most of the code to ensure it does what I expected it to do. I did simulate the counting of likes and unlikes since I don't have comments like yours. We know that part of your code works anyway. All else is working on my site, so why not yours?? Very odd!

  10. edow
    Member
    Posted 4 months ago #

    I'm sorry, your code is working *shame on me*.

    But only after I call the function with:
    $counts = aigoo_get_score();
    This code shows the avatars indeed. But the extract code (below) have to work on top of the page, instead of only after the function call. Is that possible? If I call the function on top of the page, also the avatars are shown at the top of the page and that's what I don't want.

    Also I would like to show the extract code and the $totalvotes code on the category, search and tag pages. Or do I have to call the function otherwise?

    So this is the extract code (I style it later, but it works):

    extract( $counts );  //restores compacted variables
    echo "Number of Likes: $likescore\n";
    echo "Number of Unlikes: $unlikescore\n";

    And this is the working $totalvotes code:

    $totalvotes = $likescore + $unlikescore;
    echo ''.$totalvotes.'';

    So, my question now is how to show these codes on top of the page and on the category, search and tag pages.

  11. edow
    Member
    Posted 4 months ago #

    To be complete, this is my function code right now:

    function aigoo_get_score() {
       $comments = get_comments( array('post_id' => get_the_ID(),) );
    			$likes = array();
    			$unlikes = array();
    			foreach( $comments as $comment ) {
    				if('unlike' == $comment->comment_content ) $unlikes[] = $comment;
    					else $likes[] = $comment;
    			}
    	echo '<div class="upvoters" id="votes">';
    	echo '<span class="numberoflikes">('.count($likes).')</span>';
    	echo '<div class="upvoter-img">';
    	foreach( $likes as $like )
    		echo("<img src=\"".get_avatar_url(get_avatar( $like->comment_author_email, 40 ))."\" class=\"tooltip\" title=\"".$like->comment_author."\" width=\"40\" height=\"40\">");
    	echo '</div>';
    	echo '</div>';
    	echo '<div class="downvoters">';
    	echo '<span class="numberofunlikes">('.count($unlikes).')</span>';
    	echo '<div class="downvoter-img">';
    	foreach( $unlikes as $unlike )
    		echo("<img src=\"".get_avatar_url(get_avatar( $unlike->comment_author_email, 40 ))."\" class=\"tooltip\" title=\"".$unlike->comment_author."\" width=\"40\" height=\"40\">");
    	echo '</div>';
    	echo '</div>';
        $likescore = count( $likes );
    	$unlikescore = count( $unlikes );
    	return compact('likescore', 'unlikescore');
    }
  12. edow
    Member
    Posted 4 months ago #

    I tried the following code on top of the single.php page:

    $counts = aigoo_get_score();
    			extract( $counts );  //restores compacted variables
    			$score = $likescore - $unlikescore;
    			$totalvotes = $likescore + $unlikescore;
    			if ($score > 0 )
    				{
    				echo '<span class="plusscore">+'.$score.'</span><br>';
    				}
    			elseif ($score == 0 )
    				{
    				echo '<span class="zeroscore">'.$score.'</span><br>';
    				}
    			elseif ($score < 0 )
    				{
    				echo '<span class="minusscore">'.$score.'</span><br>';
    				}
    			if ($totalvotes == 1 )
    				{
    				echo '<span class="totalvotes">Score uit <a href="#comments">'.$totalvotes.' stem</a></span>';
    				}
    			elseif ($totalvotes == -1 )
    				{
    				echo '<span class="totalvotes">Score uit <a href="#comments">'.$totalvotes.' stem</a></span>';
    				}
    			elseif ($totalvotes == 0 )
    				{
    				echo '<span class="totalvotes"><a href="#comments">Nu stemmen!</a></span>';
    				}
    			else
    				{
    				echo '<span class="totalvotes">Score uit <a href="#comments">'.$totalvotes.' stemmen</a></span>';
    				}

    And this where the avatars should be on single.php:

    echo '<div class="upvoters" id="votes">';
    				echo '<span class="numberoflikes">('.count($likes).')</span>';
    				echo '<div class="upvoter-img">';
    				foreach( $likes as $like )
    					echo("<img src=\"".get_avatar_url(get_avatar( $like->comment_author_email, 40 ))."\" class=\"tooltip\" title=\"".$like->comment_author."\" width=\"40\" height=\"40\">");
    				echo '</div>';
    				echo '</div>';
    				echo '<div class="downvoters">';
    				echo '<span class="numberofunlikes">('.count($unlikes).')</span>';
    				echo '<div class="downvoter-img">';
    				foreach( $unlikes as $unlike )
    					echo("<img src=\"".get_avatar_url(get_avatar( $unlike->comment_author_email, 40 ))."\" class=\"tooltip\" title=\"".$unlike->comment_author."\" width=\"40\" height=\"40\">");
    				echo '</div>';
    				echo '</div>';

    And this in functions.php:

    /* Display likes/unlikes */
    function aigoo_get_score() {
       $comments = get_comments( array('post_id' => get_the_ID(),) );
    			$likes = array();
    			$unlikes = array();
    			foreach( $comments as $comment ) {
    				if('unlike' == $comment->comment_content ) $unlikes[] = $comment;
    					else $likes[] = $comment;
    			}
        $likescore = count( $likes );
    	$unlikescore = count( $unlikes );
    	return compact('likescore', 'unlikescore');
    }

    Now, the code on top of the page is working correctly, but there're no avatars shown at the bottom of the page.
    My idea was to remove the avatars code from the function and put it on the single.php page itself, so then I could call the function on top of the page.

    This is the code I use on for example the category page and it looks like it works correctly:

    $counts = aigoo_get_score();
    					extract( $counts );  //restores compacted variables
    					$score = $likescore - $unlikescore;
    					$totalvotes = $likescore + $unlikescore;
    
    if ($score > 0 )
    					{
    					echo '<span>Score +'.$score.'</span>';
    					}
    					elseif ($score == 0 )
    						{
    						echo '<span>Score '.$score.'</span>';
    						}
    					elseif ($score < 0 )
    						{
    						echo '<span>Score '.$score.'</span>';
    						}
    					if ($totalvotes == 1 )
    						{
    						echo '<span> uit '.$totalvotes.' stem</span>';
    						}
    					elseif ($totalvotes == -1 )
    						{
    						echo '<span> uit '.$totalvotes.' stem</span>';
    						}
    					elseif ($totalvotes == 0 )
    						{
    						echo '<span>Nu stemmen!</span>';
    						}
    					else
    						{
    						echo '<span> uit '.$totalvotes.' stemmen</span>';
    						}

    So, right now I only need the avatars to show. Further, I'm very very happy with this function!

  13. edow
    Member
    Posted 4 months ago #

    The avatars are only shown when I use this code in the function itself, but not when I hard coded it on single.php:

    echo '<div class="upvoters" id="votes">';
    				echo '<div class="upvoter-img">';
    				foreach( $likes as $like )
    					echo("<img src=\"".get_avatar_url(get_avatar( $like->comment_author_email, 40 ))."\" class=\"tooltip\" title=\"".$like->comment_author."\" width=\"40\" height=\"40\">");
    				echo '</div>';
    				echo '</div>';
    				echo '<div class="downvoters">';
    				echo '<div class="downvoter-img">';
    				foreach( $unlikes as $unlike )
    					echo("<img src=\"".get_avatar_url(get_avatar( $unlike->comment_author_email, 40 ))."\" class=\"tooltip\" title=\"".$unlike->comment_author."\" width=\"40\" height=\"40\">");
    				echo '</div>';
    				echo '</div>';

    I only need it on single.php, because for example on category.php I only show to score and not the avatars. The rest is working great though. Awesome!

  14. edow
    Member
    Posted 4 months ago #

    ...to be clear, if I use the above code in the function itself it is not showing on the right place. So I need it hard coded in single.php I guess.

  15. bcworkz
    Member
    Posted 4 months ago #

    You are running into scope issues again. The function establishes the like and unlike arrays and determines the counts, which are returned. This is why the function must be called before anything else is output. Since the avatars are inappropriate when the function needs to be called, then the function cannot output avatars. The avatar code needs to reside where the avatars need to appear, not in the function.

    The problem then is the like and unlike arrays used by the avatar code are not available to it because they were established in the function, making the arrays out of scope. There's all sorts of ways to deal with this. I suggest the function not return scores, but actually return the like and unlike arrays required by the avatar code. The arrays can be compacted just like single values are for return from the function. Then extracting the returned value will restore the arrays, where they will now be in scope for the avatar code to use.

    Where ever you want to display scores, just get the counts from the extracted arrays. I'm not going to take the time to write out all the code because I think you have all the parts and have learned enough that you can pull this together yourself. I will outline all the steps, you just need to code them.

    The function: get the comments and sort them into like and unlike arrays. Compact the two arrays and return the compacted value.

    The template: call the above function, assign the returned value to a variable. Extract that variable to restore the like and unlike arrays.

    Show scores: use count() on the restored arrays and apply any math as needed to arrive at the values to output.

    Show avatars: step through the like and unlike arrays to output the avatar corresponding to each comment author.

    I think you can do this! But if you get stuck, post your best effort and I'll set you straight. Good luck!

  16. edow
    Member
    Posted 4 months ago #

    You're very helpful and I appreciate all the time you spent to help me. Many thanks! I think I've got it now.

    I was following your step-by-step advise and before I was by the last step it was working already.

    My function now is:

    function aigoo_get_score() {
       $comments = get_comments( array('post_id' => get_the_ID(),) );
    			$likes = array();
    			$unlikes = array();
    			foreach( $comments as $comment ) {
    				if('unlike' == $comment->comment_content ) $unlikes[] = $comment;
    					else $likes[] = $comment;
    			}
        $likescore = count( $likes );
    	$unlikescore = count( $unlikes );
    	$score = count($likes) - count($unlikes);
    	$totalvotes = count($likes) + count($unlikes);
    	return compact('likes', 'unlikes', 'likescore', 'unlikescore', 'score', 'totalvotes');
    }

    I compacted the like and unlike arrays and also the score and totalvotes counts.

    In single.php I call the function with:

    $counts = aigoo_get_score();
    extract( $counts );

    and than echo $score and $totalvotes for the counts.

    To show the avatars I didn't need to modify the code. This is the code I use:

    echo '<div class="upvoters" id="votes">';
    				echo '<div class="upvoter-img">';
    				foreach( $likes as $like )
    					echo("<img src=\"".get_avatar_url(get_avatar( $like->comment_author_email, 40 ))."\" class=\"tooltip\" title=\"".$like->comment_author."\" width=\"40\" height=\"40\">");
    				echo '</div>';
    				echo '</div>';
    				echo '<div class="downvoters">';
    				echo '<div class="downvoter-img">';
    				foreach( $unlikes as $unlike )
    					echo("<img src=\"".get_avatar_url(get_avatar( $unlike->comment_author_email, 40 ))."\" class=\"tooltip\" title=\"".$unlike->comment_author."\" width=\"40\" height=\"40\">");
    				echo '</div>';
    				echo '</div>';

    English and coding ;) are not my native languages, but hopefully I followed your steps properly. It looks like it's working well. I guess when it's working it's alright? I don't want problems later on, so if you (or someone else of course) foresees problems I'll do my best to improve this code.

    If the code is fine I would to thank you very much for teaching me all this! I've learned a lot with all your help!

  17. bcworkz
    Member
    Posted 4 months ago #

    Your implementation is slightly different than what I had in mind, but carried out correctly, so it's all good. Your code looks fine, and the fact it's working confirms it. If it is doing exactly what you want, there is no need to change anything. You will not have any future problems. Well done!

    I'm pleased you finally got what you wanted and were able to learn along the way. Your command of English is excellent. While you did misunderstand me a few times, I am very bad at communicating clearly with non-native English speakers, so the fault is mine, not yours. Even native speakers often do not understand me!

  18. edow
    Member
    Posted 4 months ago #

    Your instructions were very clear! I'm also glad it worked out as I wanted. Thanks!

  19. edow
    Member
    Posted 2 months ago #

    I feel guilty to ask something again in this topic, but it seems to me this is the best place to ask it.

    As seen above I use this code to show the post score:

    <?php
    $counts = aigoo_get_score();
    			extract( $counts );  //restores compacted variables
    
    <span>+'.$score.'</span>
    ?>

    The following code is showing the latest 5 posts with the most comments in a specific category on my homepage:

    <?php
    			$popular = new WP_Query( array(
    				'post_type'             => array( 'post' ),
    				'showposts'             => 5,
    				'cat'                   => 'activiteit',
    				'ignore_sticky_posts'   => true,
    				'orderby'               => 'comment_count',
    				'order'                 => 'dsc',
    				'date_query' => array(
    					array(
    						'after' => '0',
    					),
    				),
    			) );
    		?>
    		<?php while ( $popular->have_posts() ): $popular->the_post(); ?>
    			<li><a href="<?php the_permalink() ?>"><?php the_title(); ?></a> (<?php comments_number( 'Nu stemmen!', '1', '%' ); ?>)</li>
    		<?php endwhile; ?>

    How can I make it happen that instead of showing the posts with the most comments it shows the posts with the highest voted comments on my homepage?

    I don't know if it's even possible.

    To be complete, this is in my functions.php:

    <?php
    /* Display likes/unlikes */
    function aigoo_get_score() {
       $comments = get_comments( array('post_id' => get_the_ID(),) );
    			$likes = array();
    			$unlikes = array();
    			foreach( $comments as $comment ) {
    				if('unlike' == $comment->comment_content ) $unlikes[] = $comment;
    					else $likes[] = $comment;
    			}
        $likescore = count( $likes );
    	$unlikescore = count( $unlikes );
    	$score = count($likes) - count($unlikes);
    	$totalvotes = count($likes) + count($unlikes);
    	return compact('likes', 'unlikes', 'likescore', 'unlikescore', 'score', 'totalvotes');
    }
    ?>
  20. esmi
    Forum Moderator
    Posted 2 months ago #

    If you require assistance then please post a new topic. I am now closing this 3 month old resolved topic as it references an older version of WordPress.

Topic Closed

This topic has been closed to new replies.

About this Topic

Tags

No tags yet.