<!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>[40967] trunk/src/wp-admin/includes: Docs: Provide best practice guidance for achieving parity between `$menu_slug` values supplied when adding menu and submenu pages, and later trying to compare those initial values against sanitized screen IDs derived from `$menu_slug`.</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 { 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/40967">40967</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/40967","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>DrewAPicture</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2017-06-30 04:17:56 +0000 (Fri, 30 Jun 2017)</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'>Docs: Provide best practice guidance for achieving parity between `$menu_slug` values supplied when adding menu and submenu pages, and later trying to compare those initial values against sanitized screen IDs derived from `$menu_slug`.

At the heart of the matter, the `$menu_slug` parameter in `add_menu_page()` and `add_submenu_page()` is not sanitized with `sanitize_key()`. When the screen object is later built for the admin page, the screen ID is derived from that `$menu_slug` value, though passed through `sanitize_key()`, which can produce unexpected results in comparison check.

Changing the sanitization code to provide actual parity is out of the question at this juncture, so updating the docs to describe how to avoid this edge case is the next best option.

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

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunksrcwpadminincludespluginphp">trunk/src/wp-admin/includes/plugin.php</a></li>
<li><a href="#trunksrcwpadminincludestemplatephp">trunk/src/wp-admin/includes/template.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunksrcwpadminincludespluginphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-admin/includes/plugin.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-admin/includes/plugin.php    2017-06-30 03:43:41 UTC (rev 40966)
+++ trunk/src/wp-admin/includes/plugin.php      2017-06-30 04:17:56 UTC (rev 40967)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1060,7 +1060,9 @@
</span><span class="cx" style="display: block; padding: 0 10px">  * @param string   $page_title The text to be displayed in the title tags of the page when the menu is selected.
</span><span class="cx" style="display: block; padding: 0 10px">  * @param string   $menu_title The text to be used for the menu.
</span><span class="cx" style="display: block; padding: 0 10px">  * @param string   $capability The capability required for this menu to be displayed to the user.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param string   $menu_slug  The slug name to refer to this menu by (should be unique for this menu).
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param string   $menu_slug  The slug name to refer to this menu by. Should be unique for this menu page and only
+ *                             include lowercase alphanumeric, dashes, and underscores characters to be compatible
+ *                             with sanitize_key().
</ins><span class="cx" style="display: block; padding: 0 10px">  * @param callable $function   The function to be called to output the content for this page.
</span><span class="cx" style="display: block; padding: 0 10px">  * @param string   $icon_url   The URL to the icon to be used for this menu.
</span><span class="cx" style="display: block; padding: 0 10px">  *                             * Pass a base64-encoded SVG using a data URI, which will be colored to match
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1126,11 +1128,15 @@
</span><span class="cx" style="display: block; padding: 0 10px">  * @global array $_registered_pages
</span><span class="cx" style="display: block; padding: 0 10px">  * @global array $_parent_pages
</span><span class="cx" style="display: block; padding: 0 10px">  *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param string   $parent_slug The slug name for the parent menu (or the file name of a standard WordPress admin page).
- * @param string   $page_title  The text to be displayed in the title tags of the page when the menu is selected.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param string   $parent_slug The slug name for the parent menu (or the file name of a standard
+ *                              WordPress admin page).
+ * @param string   $page_title  The text to be displayed in the title tags of the page when the menu
+ *                              is selected.
</ins><span class="cx" style="display: block; padding: 0 10px">  * @param string   $menu_title  The text to be used for the menu.
</span><span class="cx" style="display: block; padding: 0 10px">  * @param string   $capability  The capability required for this menu to be displayed to the user.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param string   $menu_slug   The slug name to refer to this menu by (should be unique for this menu).
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param string   $menu_slug   The slug name to refer to this menu by. Should be unique for this menu
+ *                              and only include lowercase alphanumeric, dashes, and underscores characters
+ *                              to be compatible with sanitize_key().
</ins><span class="cx" style="display: block; padding: 0 10px">  * @param callable $function    The function to be called to output the content for this page.
</span><span class="cx" style="display: block; padding: 0 10px">  * @return false|string The resulting page's hook_suffix, or false if the user does not have the capability required.
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span></span></pre></div>
<a id="trunksrcwpadminincludestemplatephp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-admin/includes/template.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-admin/includes/template.php  2017-06-30 03:43:41 UTC (rev 40966)
+++ trunk/src/wp-admin/includes/template.php    2017-06-30 04:17:56 UTC (rev 40967)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -892,7 +892,10 @@
</span><span class="cx" style="display: block; padding: 0 10px">  * @param string|array|WP_Screen $screen        Optional. The screen or screens on which to show the box
</span><span class="cx" style="display: block; padding: 0 10px">  *                                              (such as a post type, 'link', or 'comment'). Accepts a single
</span><span class="cx" style="display: block; padding: 0 10px">  *                                              screen ID, WP_Screen object, or array of screen IDs. Default
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- *                                              is the current screen.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ *                                              is the current screen.  If you have used add_menu_page() or 
+ *                                              add_submenu_page() to create a new screen (and hence screen_id),
+ *                                              make sure your menu slug conforms to the limits of sanitize_key()
+ *                                              otherwise the 'screen' menu may not correctly render on your page.
</ins><span class="cx" style="display: block; padding: 0 10px">  * @param string                 $context       Optional. The context within the screen where the boxes
</span><span class="cx" style="display: block; padding: 0 10px">  *                                              should display. Available contexts vary from screen to
</span><span class="cx" style="display: block; padding: 0 10px">  *                                              screen. Post edit screen contexts include 'normal', 'side',
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -987,7 +990,11 @@
</span><span class="cx" style="display: block; padding: 0 10px">  * @global array $wp_meta_boxes
</span><span class="cx" style="display: block; padding: 0 10px">  *
</span><span class="cx" style="display: block; padding: 0 10px">  * @staticvar bool $already_sorted
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param string|WP_Screen $screen  Screen identifier
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ *
+ * @param string|WP_Screen $screen  Screen identifier. If you have used add_menu_page() or
+ *                                  add_submenu_page() to create a new screen (and hence screen_id)
+ *                                  make sure your menu slug conforms to the limits of sanitize_key()
+ *                                  otherwise the 'screen' menu may not correctly render on your page.
</ins><span class="cx" style="display: block; padding: 0 10px">  * @param string           $context box context
</span><span class="cx" style="display: block; padding: 0 10px">  * @param mixed            $object  gets passed to the box callback function as first parameter
</span><span class="cx" style="display: block; padding: 0 10px">  * @return int number of meta_boxes
</span></span></pre>
</div>
</div>

</body>
</html>