<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[58875] trunk: Comments: Add optional `$context` parameter to `get_edit_comment_link()` to get the URL without HTML entities.</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { white-space: pre-line; overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta" style="font-size: 105%">
<dt style="float: left; width: 6em; font-weight: bold">Revision</dt> <dd><a style="font-weight: bold" href="https://core.trac.wordpress.org/changeset/58875">58875</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"https://core.trac.wordpress.org/changeset/58875","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>flixos90</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2024-08-09 17:59:41 +0000 (Fri, 09 Aug 2024)</dd>
</dl>

<pre style='padding-left: 1em; margin: 2em 0; border-left: 2px solid #ccc; line-height: 1.25; font-size: 105%; font-family: sans-serif'>Comments: Add optional `$context` parameter to `get_edit_comment_link()` to get the URL without HTML entities.

This brings the function in line with the similar `get_edit_post_link()` parameter. The 'get_edit_comment_link' filter now additionally receives the `$comment_id` and `$context` as parameters.

Additionally, as a minor enhancement, the capability check is now more defensive, as it will no longer cause an error if the given comment ID is invalid.

As part of the changeset, comprehensive test coverage for the `get_edit_comment_link()` including the new behavior is added.

Props deepakrohilla.
Fixes <a href="https://core.trac.wordpress.org/ticket/61727">#61727</a>.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunksrcwpincludeslinktemplatephp">trunk/src/wp-includes/link-template.php</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunktestsphpunittestslinkgetEditCommentLinkphp">trunk/tests/phpunit/tests/link/getEditCommentLink.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunksrcwpincludeslinktemplatephp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/link-template.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/link-template.php   2024-08-09 15:38:13 UTC (rev 58874)
+++ trunk/src/wp-includes/link-template.php     2024-08-09 17:59:41 UTC (rev 58875)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1595,27 +1595,39 @@
</span><span class="cx" style="display: block; padding: 0 10px">  * Retrieves the edit comment link.
</span><span class="cx" style="display: block; padding: 0 10px">  *
</span><span class="cx" style="display: block; padding: 0 10px">  * @since 2.3.0
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @since 6.7.0 The $context parameter was added.
</ins><span class="cx" style="display: block; padding: 0 10px">  *
</span><span class="cx" style="display: block; padding: 0 10px">  * @param int|WP_Comment $comment_id Optional. Comment ID or WP_Comment object.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @return string|void The edit comment link URL for the given comment.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param string         $context    Optional. Context in which the URL should be used. Either 'display',
+ *                                   to include HTML entities, or 'url'. Default 'display'.
+ * @return string|void The edit comment link URL for the given comment, or void if the comment id does not exist or
+ *                     the current user is not allowed to edit it.
</ins><span class="cx" style="display: block; padding: 0 10px">  */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-function get_edit_comment_link( $comment_id = 0 ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+function get_edit_comment_link( $comment_id = 0, $context = 'display' ) {
</ins><span class="cx" style="display: block; padding: 0 10px">         $comment = get_comment( $comment_id );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        if ( ! current_user_can( 'edit_comment', $comment->comment_ID ) ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if ( ! is_object( $comment ) || ! current_user_can( 'edit_comment', $comment->comment_ID ) ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                 return;
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        $location = admin_url( 'comment.php?action=editcomment&amp;c=' ) . $comment->comment_ID;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if ( 'display' === $context ) {
+               $action = 'comment.php?action=editcomment&amp;c=';
+       } else {
+               $action = 'comment.php?action=editcomment&c=';
+       }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        $location = admin_url( $action ) . $comment->comment_ID;
+
</ins><span class="cx" style="display: block; padding: 0 10px">         /**
</span><span class="cx" style="display: block; padding: 0 10px">         * Filters the comment edit link.
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-         * @since 2.3.0
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  * @since 6.7.0 The $comment_id and $context parameters are now being passed to the filter.
</ins><span class="cx" style="display: block; padding: 0 10px">          *
</span><span class="cx" style="display: block; padding: 0 10px">         * @param string $location The edit link.
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         * @param int    $comment_id Optional. Unique ID of the comment to generate an edit link.
+        * @param int    $context    Optional. Context to include HTML entities in link. Default 'display'.
</ins><span class="cx" style="display: block; padding: 0 10px">          */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        return apply_filters( 'get_edit_comment_link', $location );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ return apply_filters( 'get_edit_comment_link', $location, $comment_id, $context );
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span></span></pre></div>
<a id="trunktestsphpunittestslinkgetEditCommentLinkphp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: trunk/tests/phpunit/tests/link/getEditCommentLink.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/link/getEditCommentLink.php                             (rev 0)
+++ trunk/tests/phpunit/tests/link/getEditCommentLink.php       2024-08-09 17:59:41 UTC (rev 58875)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,130 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+/**
+ * @group link
+ * @group comment
+ * @covers ::get_edit_comment_link
+ */
+class Tests_Link_GetEditCommentLink extends WP_UnitTestCase {
+
+       public static $comment_id;
+       public static $user_ids;
+
+       public static function wpSetUpBeforeClass( WP_UnitTest_Factory $factory ) {
+               self::$comment_id = $factory->comment->create( array( 'comment_content' => 'Test comment' ) );
+
+               self::$user_ids = array(
+                       'admin'      => $factory->user->create( array( 'role' => 'administrator' ) ),
+                       'subscriber' => $factory->user->create( array( 'role' => 'subscriber' ) ),
+               );
+       }
+
+       public static function wpTearDownAfterClass() {
+               // Delete the test comment.
+               wp_delete_comment( self::$comment_id, true );
+
+               // Delete the test users.
+               foreach ( self::$user_ids as $user_id ) {
+                       self::delete_user( $user_id );
+               }
+       }
+
+       public function set_up() {
+               parent::set_up();
+               wp_set_current_user( self::$user_ids['admin'] );
+       }
+
+       /**
+        * Tests that get_edit_comment_link() returns the correct URL by default.
+        */
+       public function test_get_edit_comment_link_default() {
+               $comment_id   = self::$comment_id;
+               $expected_url = admin_url( 'comment.php?action=editcomment&amp;c=' . $comment_id );
+               $actual_url   = get_edit_comment_link( $comment_id );
+
+               $this->assertSame( $expected_url, $actual_url );
+       }
+
+       /**
+        * Tests that get_edit_comment_link() returns the correct URL with a context of 'display'.
+        *
+        * The expected result should include HTML entities.
+        *
+        * @ticket 61727
+        */
+       public function test_get_edit_comment_link_display_context() {
+               $comment_id   = self::$comment_id;
+               $expected_url = admin_url( 'comment.php?action=editcomment&amp;c=' . $comment_id );
+               $actual_url   = get_edit_comment_link( $comment_id, 'display' );
+
+               $this->assertSame( $expected_url, $actual_url );
+       }
+
+       /**
+        * Tests that get_edit_comment_link() returns the correct URL with a context of 'url'.
+        *
+        * The expected result should not include HTML entities.
+        *
+        * @ticket 61727
+        */
+       public function test_get_edit_comment_link_url_context() {
+               $comment_id   = self::$comment_id;
+               $expected_url = admin_url( 'comment.php?action=editcomment&c=' . $comment_id );
+               $actual_url   = get_edit_comment_link( $comment_id, 'url' );
+
+               $this->assertSame( $expected_url, $actual_url );
+       }
+
+       /**
+        * Tests that get_edit_comment_link() returns nothing if the comment ID is invalid.
+        *
+        * @ticket 61727
+        */
+       public function test_get_edit_comment_link_invalid_comment() {
+               $comment_id         = 12345;
+               $actual_url_display = get_edit_comment_link( $comment_id, 'display' );
+               $actual_url         = get_edit_comment_link( $comment_id, 'url' );
+
+               $this->assertNull( $actual_url_display );
+               $this->assertNull( $actual_url );
+       }
+
+       /**
+        * Tests that get_edit_comment_link() returns nothing if the current user cannot edit it.
+        */
+       public function test_get_edit_comment_link_user_cannot_edit() {
+               wp_set_current_user( self::$user_ids['subscriber'] );
+               $comment_id         = self::$comment_id;
+               $actual_url_display = get_edit_comment_link( $comment_id, 'display' );
+               $actual_url         = get_edit_comment_link( $comment_id, 'url' );
+
+               $this->assertNull( $actual_url_display );
+               $this->assertNull( $actual_url );
+       }
+
+       /**
+        * Tests that the 'get_edit_comment_link' filter works as expected, including the additional parameters.
+        *
+        * @ticket 61727
+        */
+       public function test_get_edit_comment_link_filter() {
+               $comment_id           = self::$comment_id;
+               $expected_url_display = admin_url( 'comment-test.php?context=display' );
+               $expected_url         = admin_url( 'comment-test.php?context=url' );
+
+               add_filter(
+                       'get_edit_comment_link',
+                       function ( $location, $comment_id, $context ) {
+                               return admin_url( 'comment-test.php?context=' . $context );
+                       },
+                       10,
+                       3
+               );
+
+               $actual_url_display = get_edit_comment_link( $comment_id, 'display' );
+               $actual_url         = get_edit_comment_link( $comment_id, 'url' );
+
+               // Assert the final URLs are as expected
+               $this->assertSame( $expected_url_display, $actual_url_display );
+               $this->assertSame( $expected_url, $actual_url );
+       }
+}
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: trunk/tests/phpunit/tests/link/getEditCommentLink.php
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:eol-style</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+native
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span></div>

</body>
</html>