<!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>[13460] sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory: Plugin Directory: Extract the trademark logic from the upload handler, into a generic class for use in the plugin directory.</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="http://meta.trac.wordpress.org/changeset/13460">13460</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"http://meta.trac.wordpress.org/changeset/13460","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>dd32</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2024-04-05 03:44:27 +0000 (Fri, 05 Apr 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'>Plugin Directory: Extract the trademark logic from the upload handler, into a generic class for use in the plugin directory.

See <a href="http://meta.trac.wordpress.org/ticket/5868">#5868</a>, <a href="http://meta.trac.wordpress.org/ticket/6108">#6108</a>.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentpluginsplugindirectoryapiroutesclasspluginuploadphp">sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/api/routes/class-plugin-upload.php</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentpluginsplugindirectoryreadmeclassvalidatorphp">sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/readme/class-validator.php</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentpluginsplugindirectoryshortcodesclassuploadhandlerphp">sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/shortcodes/class-upload-handler.php</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentpluginsplugindirectoryclasstrademarksphp">sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/class-trademarks.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentpluginsplugindirectoryapiroutesclasspluginuploadphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/api/routes/class-plugin-upload.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/api/routes/class-plugin-upload.php      2024-04-05 03:07:40 UTC (rev 13459)
+++ sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/api/routes/class-plugin-upload.php        2024-04-05 03:44:27 UTC (rev 13460)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -142,16 +142,17 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                // Duplicated from Upload handler.
</span><span class="cx" style="display: block; padding: 0 10px">                // Make sure it doesn't use a TRADEMARK protected slug.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                if ( false !== $upload_handler->has_trademarked_slug()  ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $has_trademarked_slug = Trademarks::check_slug( $slug, wp_get_current_user() );
+               if ( $has_trademarked_slug ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                         $error = __( 'That plugin slug includes a restricted term.', 'wporg-plugins' );
</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 ( $upload_handler->has_trademarked_slug() === trim( $upload_handler->has_trademarked_slug(), '-' ) ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 if ( $has_trademarked_slug === trim( $has_trademarked_slug, '-' ) ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                                 // Trademarks that do NOT end in "-" indicate slug cannot contain term at all.
</span><span class="cx" style="display: block; padding: 0 10px">                                $message = sprintf(
</span><span class="cx" style="display: block; padding: 0 10px">                                        /* translators: 1: plugin slug, 2: trademarked term, 3: 'Plugin Name:', 4: plugin email address */
</span><span class="cx" style="display: block; padding: 0 10px">                                        __( 'Your chosen plugin slug - %1$s - contains the restricted term "%2$s", which cannot be used at all in your plugin permalink nor the display name.', 'wporg-plugins' ),
</span><span class="cx" style="display: block; padding: 0 10px">                                        '<code>' . $slug . '</code>',
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                        trim( $upload_handler->has_trademarked_slug(), '-' )
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                 '<code>' . trim( $has_trademarked_slug, '-' ) . '</code>'
</ins><span class="cx" style="display: block; padding: 0 10px">                                 );
</span><span class="cx" style="display: block; padding: 0 10px">                        } else {
</span><span class="cx" style="display: block; padding: 0 10px">                                // Trademarks ending in "-" indicate slug cannot BEGIN with that term.
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -159,7 +160,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                        /* translators: 1: plugin slug, 2: trademarked term, 3: 'Plugin Name:', 4: plugin email address */
</span><span class="cx" style="display: block; padding: 0 10px">                                        __( 'Your chosen plugin slug - %1$s - contains the restricted term "%2$s" and cannot be used to begin your permalink or display name. We disallow the use of certain terms in ways that are abused, or potentially infringe on and/or are misleading with regards to trademarks.', 'wporg-plugins' ),
</span><span class="cx" style="display: block; padding: 0 10px">                                        '<code>' . $slug . '</code>',
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                        trim( $upload_handler->has_trademarked_slug(), '-' )
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                 '<code>' . trim( $has_trademarked_slug, '-' ) . '</code>'
</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="sitestrunkwordpressorgpublic_htmlwpcontentpluginsplugindirectoryclasstrademarksphp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/class-trademarks.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/class-trademarks.php                            (rev 0)
+++ sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/class-trademarks.php      2024-04-05 03:44:27 UTC (rev 13460)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,291 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+namespace WordPressdotorg\Plugin_Directory;
+
+use WP_Post;
+use WP_User;
+
+/**
+ * Validate trademarks for a plugin.
+ *
+ * @package WordPressdotorg\Plugin_Directory
+ */
+class Trademarks {
+
+       /**
+        * List of trademarked slugs.
+        *
+        * @var array
+        */
+       public static $trademarked_slugs = array(
+               'adobe-',
+               'adsense-',
+               'advanced-custom-fields-',
+               'adwords-',
+               'akismet-',
+               'all-in-one-wp-migration',
+               'amazon-',
+               'android-',
+               'apple-',
+               'applenews-',
+               'applepay-',
+               'aws-',
+               'azon-',
+               'bbpress-',
+               'bing-',
+               'booking-com',
+               'bootstrap-',
+               'buddypress-',
+               'chatgpt-',
+               'chat-gpt-',
+               'cloudflare-',
+               'contact-form-7-',
+               'cpanel-',
+               'disqus-',
+               'divi-',
+               'dropbox-',
+               'easy-digital-downloads-',
+               'elementor-',
+               'envato-',
+               'fbook',
+               'facebook',
+               'fb-',
+               'fb-messenger',
+               'fedex-',
+               'feedburner',
+               'firefox-',
+               'fontawesome-',
+               'font-awesome-',
+               'ganalytics-',
+               'gberg',
+               'github-',
+               'givewp-',
+               'google-',
+               'googlebot-',
+               'googles-',
+               'gravity-form-',
+               'gravity-forms-',
+               'gravityforms-',
+               'gtmetrix-',
+               'gutenberg',
+               'guten-',
+               'hubspot-',
+               'ig-',
+               'insta-',
+               'instagram',
+               'internet-explorer-',
+               'ios-',
+               'jetpack-',
+               'macintosh-',
+               'macos-',
+               'mailchimp-',
+               'microsoft-',
+               'ninja-forms-',
+               'oculus',
+               'onlyfans-',
+               'only-fans-',
+               'opera-',
+               'paddle-',
+               'paypal-',
+               'pinterest-',
+               'plugin',
+               'skype-',
+               'stripe-',
+               'tiktok-',
+               'tik-tok-',
+               'trustpilot',
+               'twitch-',
+               'twitter-',
+               'tweet',
+               'ups-',
+               'usps-',
+               'vvhatsapp',
+               'vvcommerce',
+               'vva-',
+               'vvoo',
+               'wa-',
+               'webpush-vn',
+               'wh4tsapps',
+               'whatsapp',
+               'whats-app',
+               'watson',
+               'windows-',
+               'wocommerce',
+               'woocom-',
+               'woocommerce',  // technically ending with '-for-woocommerce' is allowed.
+               'woocomerce',
+               'woo-commerce',
+               'woo-',
+               'wo-',
+               'wordpress',
+               'wordpess',
+               'wpress',
+               'wp-',
+               'wp-mail-smtp-',
+               'yandex-',
+               'yahoo-',
+               'yoast',
+               'youtube-',
+               'you-tube-',
+       );
+
+       /**
+        * List of trademark exceptions.
+        *
+        * @var array
+        */
+       public static $trademark_exceptions = array(
+               'adobe.com'             => array( 'adobe' ),
+               'automattic.com'        => array( 'akismet', 'akismet-', 'jetpack', 'jetpack-', 'wordpress', 'wp-', 'woo', 'woo-', 'woocommerce', 'woocommerce-' ),
+               'facebook.com'          => array( 'facebook', 'instagram', 'oculus', 'whatsapp' ),
+               'support.microsoft.com' => array( 'bing-', 'microsoft-' ),
+               'trustpilot.com'        => array( 'trustpilot' ),
+               'microsoft.com'         => array( 'bing-', 'microsoft-' ),
+               'yandex-team.ru'        => array( 'yandex' ),
+               'yoast.com'             => array( 'yoast' ),
+               'opera.com'             => array( 'opera-' ),
+               'adobe.com'             => array( 'adobe-' ),
+       );
+
+       /**
+        * List of trademarks that are allowed as 'for-whatever' ONLY.
+        *
+        * @var array
+        */
+       public static $for_use_exceptions = array(
+               'woocommerce',
+       );
+
+       /**
+        * List of portmanteaus, commonly used 'combo' names.
+        * To prevent things like 'woopress'.
+        *
+        * @var array
+        */
+       public static $portmanteaus = array(
+               'woo',
+       );
+
+       /**
+        * Check if a plugin name is trademarked.
+        *
+        * @param string $check                     The plugin name to check.
+        * @param array|WP_User|WP_Post $exceptions An array of exceptions to the trademark checks, or a WP_User or WP_Post object to fetch their exceptions.
+        * @return string|false The trademarked slug if found, false otherwise.
+        */
+       public static function check( $check, $exceptions = [] ) {
+               // This logic is from Upload_Handler::generate_plugin_slug()
+               $check = remove_accents( $check );
+               $check = preg_replace( '/[^a-z0-9 _.-]/i', '', $check );
+               $check = str_replace( '_', '-', $check );
+               $check = sanitize_title_with_dashes( $check );
+
+               return self::check_slug( $check, $exceptions );
+       }
+
+       /**
+        * Whether a slug-like-text passes trademark checks.
+        *
+        * @param string                $plugin_slug The slug-like-text to check.
+        * @param array|WP_User|WP_Post $exceptions  An array of exceptions to the trademark checks, or a WP_User or WP_Post object to fetch their exceptions.
+        * @return string|false The trademarked slug if found, false otherwise.
+        */
+       public static function check_slug( $plugin_slug, $exceptions = [] ) {
+               if ( $exceptions instanceof WP_User ) {
+                       $exceptions = self::get_user_exceptions( $exceptions );
+               } elseif ( $exceptions instanceof WP_Post ) {
+                       $exceptions = self::get_plugin_exceptions( $exceptions );
+               }
+
+               // The list of trademarks to check for.
+               $trademarked_slugs    = self::$trademarked_slugs;
+
+               // Domains from which exceptions would be accepted.
+               $trademark_exceptions = self::$trademark_exceptions;
+
+               // Trademarks that are allowed as 'for-whatever' ONLY.
+               $for_use_exceptions   = self::$for_use_exceptions;
+
+               // Commonly used 'combo' names (to prevent things like 'woopress').
+               $portmanteaus         = self::$portmanteaus;
+
+               // If this check has exceptions, remove those trademarks from the checks.
+               foreach ( (array) $exceptions as $exception ) {
+                       if ( ! isset( $trademark_exceptions[ $exception ] ) ) {
+                               continue;
+                       }
+
+                       // Remove any that are in the exception list.
+                       $trademarked_slugs = array_diff( $trademarked_slugs, $trademark_exceptions[ $exception ] );
+                       $portmanteaus      = array_diff( $portmanteaus, $trademark_exceptions[ $exception ] );
+               }
+
+               $has_trademarked_slug = false;
+
+               foreach ( $trademarked_slugs as $trademark ) {
+                       if ( str_ends_with( $trademark, '-' ) ) {
+                               // Trademarks ending in "-" indicate slug cannot begin with that term.
+                               if ( str_starts_with( $plugin_slug, $trademark ) ) {
+                                       $has_trademarked_slug = $trademark;
+                                       break;
+                               }
+
+                       } elseif (
+                               // Otherwise, the term cannot appear anywhere in slug.
+                               str_contains( $plugin_slug, $trademark )
+                       ) {
+                               // But first we must check to see if this is allowed as "for-TRADEMARK".
+                               if ( in_array( $trademark, $for_use_exceptions ) ) {
+                                       $for_trademark = '-for-' . $trademark;
+
+                                       // At this point we might be okay, but there's one more check.
+                                       if ( str_ends_with( $plugin_slug, $for_trademark ) ) {
+                                               // Yes the slug ENDS with 'for-TRADEMARK'.
+                                               continue; // Check the next trademark
+                                       }
+                               }
+
+                               // The term cannot exist anywhere in the plugin slug, and it's not a for-use exception.
+                               $has_trademarked_slug = $trademark;
+                               break;
+                       }
+               }
+
+               // Check portmanteaus.
+               foreach ( $portmanteaus as $portmanteau ) {
+                       if ( str_starts_with( $plugin_slug, $portmanteau ) ) {
+                               $has_trademarked_slug = $portmanteau;
+                               break;
+                       }
+               }
+
+               return $has_trademarked_slug;
+       }
+
+       /**
+        * Get list of trademark exceptions for the current user.
+        *
+        * @return array
+        */
+       public static function get_user_exceptions( $user = false ) {
+               $exceptions = [];
+
+               $user = $user ?: wp_get_current_user();
+
+               // The users email domain.
+               if ( $user && $user->exists() ) {
+                       $exceptions[] = explode( '@', $user->user_email, 2 )[1];
+               }
+
+               return $exceptions;
+       }
+
+       /**
+        * Get the exceptions allowed for a plugin.
+        *
+        * @param string $plugin_slug The plugin slug.
+        * @return array
+        */
+       public static function get_plugin_exceptions( $plugin_slug ) {
+               return [];
+       }
+}
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of file
</span><span class="cx" style="display: block; padding: 0 10px">Property changes on: sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/class-trademarks.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><a id="sitestrunkwordpressorgpublic_htmlwpcontentpluginsplugindirectoryreadmeclassvalidatorphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/readme/class-validator.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/readme/class-validator.php      2024-04-05 03:07:40 UTC (rev 13459)
+++ sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/readme/class-validator.php        2024-04-05 03:44:27 UTC (rev 13460)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2,6 +2,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> namespace WordPressdotorg\Plugin_Directory\Readme;
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> use WordPressdotorg\Plugin_Directory\Tools\Filesystem;
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+use WordPressdotorg\Plugin_Directory\Trademarks;
</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">  * A wp-admin interface to validate readme files.
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -93,10 +94,21 @@
</span><span class="cx" style="display: block; padding: 0 10px">                // Fatal errors.
</span><span class="cx" style="display: block; padding: 0 10px">                if ( isset( $readme->warnings['invalid_plugin_name_header'] ) ) {
</span><span class="cx" style="display: block; padding: 0 10px">                        $errors['invalid_plugin_name_header'] = $readme->warnings['invalid_plugin_name_header'];
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                } elseif (  empty( $readme->name ) ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         } elseif ( empty( $readme->name ) ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                         $errors['invalid_plugin_name_header'] = true;
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                if (
+                       empty( $errors['invalid_plugin_name_header'] ) &&
+                       ( $trademark_check = Trademarks::check( $readme->name, wp_get_current_user() ) )
+               ) {
+                       $errors['trademarked_name'] = [
+                               'trademark' => $trademark_check,
+                               'context'   => $readme->name,
+                               'where'     => 'readme',
+                       ];
+               }
+
</ins><span class="cx" style="display: block; padding: 0 10px">                 // Warnings & Notes.
</span><span class="cx" style="display: block; padding: 0 10px">                if ( isset( $readme->warnings['requires_header_ignored'] ) ) {
</span><span class="cx" style="display: block; padding: 0 10px">                        $warnings['requires_header_ignored'] = $readme->warnings['requires_header_ignored'];
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -382,6 +394,30 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                        '<code>License</code>'
</span><span class="cx" style="display: block; padding: 0 10px">                                );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                        case 'trademarked_name':
+                               $trademark = $data['trademark'];
+                               $context   = $data['context'];
+
+                               if ( str_ends_with( $trademark, '-' ) ) {
+                                       // Trademarks ending in "-" indicate slug cannot BEGIN with that term.
+                                       return sprintf(
+                                               /* translators: 1: plugin name/slug, 2: trademarked term, 3: plugin email address */
+                                               __( 'The plugin name includes a restricted term. Your chosen plugin name - %1$s - contains the restricted term "%2$s" and cannot be used to begin your slug, permalink, display name, or plugin name. We disallow the use of certain terms in ways that are abused, or potentially infringe on and/or are misleading with regards to trademarks. If you feel this is in error, such as you legally own the trademark for the term, please email us at %4$s and explain your situation.', 'wporg-plugins' ),
+                                               '<code>' . esc_html( $context ) . '</code>',
+                                               '<code>' . esc_html( trim( $trademark, '-' ) ) . '</code>',
+                                               '<code>plugins@wordpress.org</code>'
+                                       );
+                               } else {
+                                       // Trademarks that do NOT end in "-" indicate slug cannot contain term at all.
+                                       return sprintf(
+                                               /* translators: 1: plugin name/slug, 2: trademarked term, 3: plugin email address */
+                                               __( 'The plugin name includes a restricted term. Your chosen plugin name - %1$s - contains the restricted term "%2$s" and cannot be used at all in your plugin permalink nor the display name. If you feel this is in error, such as you legally own the trademark for a term, please email us at %3$s and explain your situation.', 'wporg-plugins' ),
+                                               '<code>' . esc_html( $context ) . '</code>',
+                                               '<code>' . esc_html( trim( $trademark, '-' ) ) . '</code>',
+                                               '<code>plugins@wordpress.org</code>'
+                                       );
+                               }
+
</ins><span class="cx" style="display: block; padding: 0 10px">                         /* The are not generated by the Readme Parser, but rather the import parser. */
</span><span class="cx" style="display: block; padding: 0 10px">                        case 'invalid_update_uri':
</span><span class="cx" style="display: block; padding: 0 10px">                                return sprintf(
</span></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentpluginsplugindirectoryshortcodesclassuploadhandlerphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/shortcodes/class-upload-handler.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/shortcodes/class-upload-handler.php     2024-04-05 03:07:40 UTC (rev 13459)
+++ sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/shortcodes/class-upload-handler.php       2024-04-05 03:44:27 UTC (rev 13460)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -7,6 +7,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> use WordPressdotorg\Plugin_Directory\Plugin_Directory;
</span><span class="cx" style="display: block; padding: 0 10px"> use WordPressdotorg\Plugin_Directory\Tools;
</span><span class="cx" style="display: block; padding: 0 10px"> use WordPressdotorg\Plugin_Directory\Tools\Filesystem;
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+use WordPressdotorg\Plugin_Directory\Trademarks;
</ins><span class="cx" style="display: block; padding: 0 10px"> use WordPressdotorg\Plugin_Directory\Admin\Tools\Upload_Token;
</span><span class="cx" style="display: block; padding: 0 10px"> use WordPressdotorg\Plugin_Directory\Clients\HelpScout;
</span><span class="cx" style="display: block; padding: 0 10px"> use WordPressdotorg\Plugin_Directory\Email\Plugin_Submission as Plugin_Submission_Email;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -168,13 +169,12 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                // Make sure it doesn't use a TRADEMARK protected slug.
</span><span class="cx" style="display: block; padding: 0 10px">                if ( ! $updating_existing ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $has_trademarked_slug = $this->has_trademarked_slug( $this->plugin_slug );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 $has_trademarked_slug = Trademarks::check_slug( $this->plugin_slug, wp_get_current_user() );
</ins><span class="cx" style="display: block; padding: 0 10px">                 } else {
</span><span class="cx" style="display: block; padding: 0 10px">                        // If we're updating an existing plugin, we need to check the new name, but the slug may be different.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $has_trademarked_slug = $this->has_trademarked_slug(
-                               $this->generate_plugin_slug( $this->plugin['Name'] )
-                       );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 $has_trademarked_slug = Trademarks::check( $this->plugin['Name'], wp_get_current_user() );
</ins><span class="cx" style="display: block; padding: 0 10px">                 }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
</ins><span class="cx" style="display: block; padding: 0 10px">                 if ( false !== $has_trademarked_slug && ! $has_upload_token ) {
</span><span class="cx" style="display: block; padding: 0 10px">                        $error = __( 'Error: The plugin name includes a restricted term.', 'wporg-plugins' );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -617,198 +617,6 @@
</span><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><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-         * Whether the uploaded plugin uses a trademark in the slug.
-        *
-        * @return string|false The trademarked slug if found, false otherwise.
-        */
-       public function has_trademarked_slug( $plugin_slug = false ) {
-               $plugin_slug = $plugin_slug ?: $this->plugin_slug;
-
-               $trademarked_slugs = array(
-                       'adobe-',
-                       'adsense-',
-                       'advanced-custom-fields-',
-                       'adwords-',
-                       'akismet-',
-                       'all-in-one-wp-migration',
-                       'amazon-',
-                       'android-',
-                       'apple-',
-                       'applenews-',
-                       'applepay-',
-                       'aws-',
-                       'azon-',
-                       'bbpress-',
-                       'bing-',
-                       'booking-com',
-                       'bootstrap-',
-                       'buddypress-',
-                       'chatgpt-',
-                       'chat-gpt-',
-                       'cloudflare-',
-                       'contact-form-7-',
-                       'cpanel-',
-                       'disqus-',
-                       'divi-',
-                       'dropbox-',
-                       'easy-digital-downloads-',
-                       'elementor-',
-                       'envato-',
-                       'fbook',
-                       'facebook',
-                       'fb-',
-                       'fb-messenger',
-                       'fedex-',
-                       'feedburner',
-                       'firefox-',
-                       'fontawesome-',
-                       'font-awesome-',
-                       'ganalytics-',
-                       'gberg',
-                       'github-',
-                       'givewp-',
-                       'google-',
-                       'googlebot-',
-                       'googles-',
-                       'gravity-form-',
-                       'gravity-forms-',
-                       'gravityforms-',
-                       'gtmetrix-',
-                       'gutenberg',
-                       'guten-',
-                       'hubspot-',
-                       'ig-',
-                       'insta-',
-                       'instagram',
-                       'internet-explorer-',
-                       'ios-',
-                       'jetpack-',
-                       'macintosh-',
-                       'macos-',
-                       'mailchimp-',
-                       'microsoft-',
-                       'ninja-forms-',
-                       'oculus',
-                       'onlyfans-',
-                       'only-fans-',
-                       'opera-',
-                       'paddle-',
-                       'paypal-',
-                       'pinterest-',
-                       'plugin',
-                       'skype-',
-                       'stripe-',
-                       'tiktok-',
-                       'tik-tok-',
-                       'trustpilot',
-                       'twitch-',
-                       'twitter-',
-                       'tweet',
-                       'ups-',
-                       'usps-',
-                       'vvhatsapp',
-                       'vvcommerce',
-                       'vva-',
-                       'vvoo',
-                       'wa-',
-                       'webpush-vn',
-                       'wh4tsapps',
-                       'whatsapp',
-                       'whats-app',
-                       'watson',
-                       'windows-',
-                       'wocommerce',
-                       'woocom-',
-                       'woocommerce',  // technically ending with '-for-woocommerce' is allowed.
-                       'woocomerce',
-                       'woo-commerce',
-                       'woo-',
-                       'wo-',
-                       'wordpress',
-                       'wordpess',
-                       'wpress',
-                       'wp-',
-                       'wp-mail-smtp-',
-                       'yandex-',
-                       'yahoo-',
-                       'yoast',
-                       'youtube-',
-                       'you-tube-',
-               );
-
-               // Domains from which exceptions would be accepted.
-               $trademark_exceptions = array(
-                       'adobe.com'             => array( 'adobe' ),
-                       'automattic.com'        => array( 'akismet', 'akismet-', 'jetpack', 'jetpack-', 'wordpress', 'wp-', 'woo', 'woo-', 'woocommerce', 'woocommerce-' ),
-                       'facebook.com'          => array( 'facebook', 'instagram', 'oculus', 'whatsapp' ),
-                       'support.microsoft.com' => array( 'bing-', 'microsoft-' ),
-                       'trustpilot.com'        => array( 'trustpilot' ),
-                       'microsoft.com'         => array( 'bing-', 'microsoft-' ),
-                       'yandex-team.ru'        => array( 'yandex' ),
-                       'yoast.com'             => array( 'yoast' ),
-                       'opera.com'             => array( 'opera-' ),
-                       'adobe.com'                             => array( 'adobe-' ),
-               );
-
-               // Trademarks that are allowed as 'for-whatever' ONLY.
-               $for_use_exceptions = array(
-                       'woocommerce',
-               );
-
-               // Commonly used 'combo' names (to prevent things like 'woopress').
-               $portmanteaus = array(
-                       'woo',
-               );
-
-               $has_trademarked_slug = false;
-
-               foreach ( $trademarked_slugs as $trademark ) {
-                       if ( '-' === $trademark[-1] ) {
-                               // Trademarks ending in "-" indicate slug cannot begin with that term.
-                               if ( 0 === strpos( $plugin_slug, $trademark ) ) {
-                                       $has_trademarked_slug = $trademark;
-                                       break;
-                               }
-                       } elseif ( false !== strpos( $plugin_slug, $trademark ) ) {
-                               // Otherwise, the term cannot appear anywhere in slug.
-                               $has_trademarked_slug = $trademark;
-                               break;
-                       }
-               }
-
-               // check for 'for-TRADEMARK' exceptions.
-               if ( $has_trademarked_slug && in_array( $has_trademarked_slug, $for_use_exceptions ) ) {
-                       $for_trademark = '-for-' . $has_trademarked_slug;
-                       // At this point we might be okay, but there's one more check.
-                       if ( $for_trademark === substr( $plugin_slug, -1 * strlen( $for_trademark ) ) ) {
-                               // Yes the slug ENDS with 'for-TRADEMARK'.
-                               $has_trademarked_slug = false;
-                       }
-               }
-
-               // Check portmanteaus.
-               foreach ( $portmanteaus as $portmanteau ) {
-                       if ( 0 === strpos( $plugin_slug, $portmanteau ) ) {
-                               $has_trademarked_slug = $portmanteau;
-                               break;
-                       }
-               }
-
-               // Get the user email domain.
-               list( ,$user_email_domain ) = explode( '@', wp_get_current_user()->user_email, 2 );
-
-               // If email domain is on our list of possible exceptions, we have an extra check.
-               if ( $has_trademarked_slug && array_key_exists( $user_email_domain, $trademark_exceptions ) ) {
-                       // If $has_trademarked_slug is in the array for that domain, they can use the term.
-                       if ( in_array( $has_trademarked_slug, $trademark_exceptions[ $user_email_domain ] ) ) {
-                               $has_trademarked_slug = false;
-                       }
-               }
-
-               return $has_trademarked_slug;
-       }
-
-       /**
</del><span class="cx" style="display: block; padding: 0 10px">          * Sends a plugin through Plugin Check.
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><span class="cx" style="display: block; padding: 0 10px">         * @return bool Whether the plugin passed the checks.
</span></span></pre>
</div>
</div>

</body>
</html>