Changeset 10214
- Timestamp:
- 08/28/2020 05:36:38 AM (4 years ago)
- Location:
- sites/trunk/wordpress.org/public_html/wp-content
- Files:
-
- 6 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/admin/class-customizations.php
r7798 r10214 59 59 add_filter( 'wp_ajax_delete-support-rep', array( __NAMESPACE__ . '\Metabox\Support_Reps', 'remove_support_rep' ) ); 60 60 add_action( 'wp_ajax_plugin-author-lookup', array( __NAMESPACE__ . '\Metabox\Author', 'lookup_author' ) ); 61 62 add_action( 'save_post', array( __NAMESPACE__ . '\Metabox\Release_Confirmation', 'save_post' ) ); 61 63 } 62 64 … … 410 412 411 413 add_meta_box( 414 'plugin-release-confirmation', 415 __( 'Plugin Release Confirmation', 'wporg-plugins' ), 416 array( __NAMESPACE__ . '\Metabox\Release_Confirmation', 'display' ), 417 'plugin', 'normal', 'high' 418 ); 419 420 add_meta_box( 412 421 'plugin-author', 413 422 __( 'Author Card', 'wporg-plugins' ), -
sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/api/class-base.php
r10073 r10214 34 34 new Routes\Plugin_Self_Close(); 35 35 new Routes\Plugin_Self_Transfer(); 36 new Routes\Plugin_Release_Confirmation(); 36 37 new Routes\Plugin_E2E_Callback(); 37 38 } -
sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/class-plugin-directory.php
r10119 r10214 587 587 add_shortcode( 'readme-validator', array( __NAMESPACE__ . '\Shortcodes\Readme_Validator', 'display' ) ); 588 588 add_shortcode( 'block-validator', array( __NAMESPACE__ . '\Shortcodes\Block_Validator', 'display' ) ); 589 590 add_shortcode( Shortcodes\Release_Confirmation::SHORTCODE, array( __NAMESPACE__ . '\Shortcodes\Release_Confirmation', 'display' ) ); 591 add_action( 'template_redirect', array( __NAMESPACE__ . '\Shortcodes\Release_Confirmation', 'template_redirect' ) ); 589 592 } 590 593 … … 603 606 'readme-validator', 604 607 'block-validator', 608 'release-confirmation', 605 609 ); 606 610 … … 1504 1508 1505 1509 return $content_pages; 1510 } 1511 1512 /** 1513 * Get a list of all Plugin Releases. 1514 */ 1515 public static function get_releases( $plugin ) { 1516 $plugin = self::get_plugin_post( $plugin ); 1517 $releases = get_post_meta( $plugin->ID, 'releases', true ); 1518 1519 // Meta doesn't exist yet? Lets fill it out. 1520 if ( false === $releases || ! is_array( $releases ) ) { 1521 update_post_meta( $plugin->ID, 'releases', [] ); 1522 1523 $tags = get_post_meta( $plugin->ID, 'tags', true ); 1524 if ( $tags ) { 1525 foreach ( $tags as $tag_version => $tag ) { 1526 self::add_release( $plugin, [ 1527 'date' => strtotime( $tag['date'] ), 1528 'tag' => $tag['tag'], 1529 'version' => $tag_version, 1530 'committer' => [ $tag['author'] ], 1531 'confirmations_required' => 0, // Old release, assume it's released. 1532 ] ); 1533 } 1534 } else { 1535 // Pull from SVN directly. 1536 $svn_tags = Tools\SVN::ls( "https://plugins.svn.wordpress.org/{$plugin->post_name}/tags/", true ) ?: []; 1537 foreach ( $svn_tags as $entry ) { 1538 // Discard files 1539 if ( 'dir' !== $entry['kind'] ) { 1540 continue; 1541 } 1542 1543 $tag = $entry['filename']; 1544 1545 // Prefix the 0 for plugin versions like 0.1 1546 if ( '.' == substr( $tag, 0, 1 ) ) { 1547 $tag = "0{$tag}"; 1548 } 1549 1550 self::add_release( $plugin, [ 1551 'date' => strtotime( $entry['date'] ), 1552 'tag' => $entry['filename'], 1553 'version' => $tag, 1554 'committer' => [ $entry['author'] ], 1555 'confirmations_required' => 0, // Old release, assume it's released. 1556 ] ); 1557 } 1558 } 1559 1560 $releases = get_post_meta( $plugin->ID, 'releases', true ) ?: []; 1561 } 1562 1563 return $releases; 1564 } 1565 1566 /** 1567 * Fetch a specific release of the plugin, by tag. 1568 */ 1569 public static function get_release( $plugin, $tag ) { 1570 $releases = self::get_releases( $plugin ); 1571 1572 $filtered = wp_list_filter( $releases, compact( 'tag' ) ); 1573 1574 if ( $filtered ) { 1575 return array_shift( $filtered ); 1576 } 1577 1578 return false; 1579 } 1580 1581 /** 1582 * Add a Plugin Release to the internal storage. 1583 */ 1584 public static function add_release( $plugin, $data ) { 1585 if ( ! isset( $data['tag'] ) ) { 1586 return false; 1587 } 1588 $plugin = self::get_plugin_post( $plugin ); 1589 1590 $release = self::get_release( $plugin, $data['tag'] ) ?: [ 1591 'date' => time(), 1592 'tag' => '', 1593 'version' => '', 1594 'zips_built' => false, 1595 'confirmations' => [], 1596 // Confirmed by default if no release confiration. 1597 'confirmed' => ! $plugin->release_confirmation, 1598 'confirmations_required' => (int) $plugin->release_confirmation, 1599 'committer' => [], 1600 'revision' => [], 1601 ]; 1602 1603 // Fill 1604 foreach ( $data as $k => $v ) { 1605 $release[ $k ] = $v; 1606 } 1607 1608 $releases = self::get_releases( $plugin ); 1609 1610 $releases[] = $release; 1611 1612 // Sort releases most recent first. 1613 uasort( $releases, function( $a, $b ) { 1614 return $b['date'] <=> $a['date']; 1615 } ); 1616 1617 return update_post_meta( $plugin->ID, 'releases', $releases ); 1506 1618 } 1507 1619 -
sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/class-template.php
r10211 r10214 787 787 788 788 /** 789 * Generates a link to self-transfer a plugin. .789 * Generates a link to self-transfer a plugin. 790 790 * 791 791 * @param int|\WP_Post|null $post Optional. Post ID or post object. Defaults to global $post. … … 798 798 array( '_wpnonce' => wp_create_nonce( 'wp_rest' ) ), 799 799 home_url( 'wp-json/plugins/v1/plugin/' . $post->post_name . '/self-transfer' ) 800 ); 801 } 802 803 /** 804 * Generates a link to enable Release Confirmations. 805 * 806 * @param int|\WP_Post|null $post Optional. Post ID or post object. Defaults to global $post. 807 * @return string URL to enable confirmations. 808 */ 809 public static function get_enable_release_confirmation_link( $post = null ) { 810 $post = get_post( $post ); 811 812 return add_query_arg( 813 array( '_wpnonce' => wp_create_nonce( 'wp_rest' ) ), 814 home_url( 'wp-json/plugins/v1/plugin/' . $post->post_name . '/release-confirmation' ) 815 ); 816 } 817 818 /** 819 * Generates a link to confirm a release. 820 * 821 * @param int|\WP_Post|null $post Optional. Post ID or post object. Defaults to global $post. 822 * @return string URL to enable confirmations. 823 */ 824 public static function get_release_confirmation_link( $tag, $post = null) { 825 $post = get_post( $post ); 826 827 return add_query_arg( 828 array( '_wpnonce' => wp_create_nonce( 'wp_rest' ) ), 829 home_url( 'wp-json/plugins/v1/plugin/' . $post->post_name . '/release-confirmation/' . $tag ) 830 ); 831 } 832 833 /** 834 * Generates a link to email the release confirmation link. 835 * 836 * @param int|\WP_Post|null $post Optional. Post ID or post object. Defaults to global $post. 837 * @return string URL to enable confirmations. 838 */ 839 public static function get_release_confirmation_access_link() { 840 return add_query_arg( 841 array( '_wpnonce' => wp_create_nonce( 'wp_rest' ) ), 842 home_url( 'wp-json/plugins/v1/release-confirmation-access' ) 800 843 ); 801 844 } -
sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/cli/class-import.php
r10199 r10214 7 7 use WordPressdotorg\Plugin_Directory\Block_JSON; 8 8 use WordPressdotorg\Plugin_Directory\Plugin_Directory; 9 use WordPressdotorg\Plugin_Directory\Email\Release_Confirmation as Release_Confirmation_Email; 9 10 use WordPressdotorg\Plugin_Directory\Readme\Parser; 10 11 use WordPressdotorg\Plugin_Directory\Template; … … 75 76 $headers = $data['plugin_headers']; 76 77 $stable_tag = $data['stable_tag']; 78 $last_committer = $data['last_committer']; 79 $last_revision = $data['last_revision']; 77 80 $tagged_versions = $data['tagged_versions']; 78 81 $last_modified = $data['last_modified']; 79 82 $blocks = $data['blocks']; 80 83 $block_files = $data['block_files']; 84 85 // Release confirmation 86 if ( $plugin->release_confirmation ) { 87 if ( 'trunk' === $stable_tag ) { 88 throw new Exception( 'Plugin cannot be released from trunk due to release confirmation being enabled.' ); 89 } 90 91 $release = Plugin_Directory::get_release( $plugin, $stable_tag ); 92 93 // This tag is unknown? Trigger email. 94 if ( ! $release ) { 95 Plugin_Directory::add_release( 96 [ 97 'tag' => $stable_tag, 98 'version' => $headers->Version, 99 'committer' => [ $last_committer ], 100 'revision' => [ $last_revision ] 101 ] 102 ); 103 104 $email = new Release_Confirmation_Email( 105 $plugin, 106 Tools::get_plugin_committers( $plugin_slug ), 107 [ 108 'release' => $releases[ $stable_tag ], 109 'who' => $last_committer, 110 'readme' => $readme, 111 'headers' => $headers, 112 ] 113 ); 114 $email->send(); 115 116 throw new Exception( 'Plugin release not confirmed; email triggered.' ); 117 } 118 119 // Check that the tag is approved. 120 if ( ! $release['confirmed'] ) { 121 122 if ( ! in_array( $last_committer, $release['committer'], true ) ) { 123 $release['committer'][] = $last_committer; 124 } 125 if ( ! in_array( $last_revision, $release['revision'], true ) ) { 126 $release['revision'][] = $last_revision; 127 } 128 129 // Update with ^ 130 Plugin_Directory::add_release( $plugin, $release ); 131 132 throw new Exception( 'Plugin release not confirmed.' ); 133 } 134 135 // At this point we can assume that the release was confirmed, and should be imported. 136 } 81 137 82 138 $content = ''; … … 261 317 } 262 318 319 $plugin = Plugin_Directory::get_plugin_post( $plugin_slug ); 320 321 // Don't rebuild release-confirmation-required tags. 322 if ( $plugin->release_confirmation ) { 323 foreach ( $versions_to_build as $i => $tag ) { 324 $release = Plugin_Directory::get_release( $plugin, $tag ); 325 326 if ( ! $release || ( $release['zips_built'] && $release['confirmations_required'] ) ) { 327 unset( $versions_to_build[ $i ] ); 328 } else { 329 $release['zips_built'] = true; 330 Plugin_Directory::add_release( $release ); 331 } 332 333 } 334 } 335 336 if ( ! $versions_to_build ) { 337 return false; 338 } 339 263 340 // Rebuild/Build $build_zips 264 341 try { … … 390 467 } 391 468 469 $last_committer = $svn_info['result']['Last Changed Author'] ?? ''; 470 $last_revision = $svn_info['result']['Last Changed Rev'] ?? 0; 471 392 472 $svn_export = SVN::export( 393 473 $stable_url, … … 549 629 } ) ); 550 630 551 return compact( 'readme', 'stable_tag', 'last_modified', ' tmp_dir', 'plugin_headers', 'assets', 'tagged_versions', 'blocks', 'block_files' );631 return compact( 'readme', 'stable_tag', 'last_modified', 'last_committer', 'last_revision', 'tmp_dir', 'plugin_headers', 'assets', 'tagged_versions', 'blocks', 'block_files' ); 552 632 } 553 633 -
sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/email/class-base.php
r10124 r10214 25 25 26 26 /** 27 * @param $plugin The plugin this email relates to.27 * @param $plugin The plugin this email relates to. 28 28 * @param $users[] A list of users to email. 29 * @param $args[] A list of args that the email requires.29 * @param $args[] A list of args that the email requires. 30 30 */ 31 public function __construct( $plugin, $users, $args = array() ) { 32 $this->plugin = Plugin_Directory::get_plugin_post( $plugin ); 31 public function __construct( $plugin, $users = [], $args = [] ) { 32 33 // Sometimes we don't have a plugin context, just a user.. 34 if ( $plugin instanceOf WP_User ) { 35 $users = [ $plugin ]; 36 $args = $users; // Just assume that args will have been passed in there. 37 38 $this->plugin = true; // To pass checks.. 39 } else { 40 $this->plugin = Plugin_Directory::get_plugin_post( $plugin ); 41 } 33 42 34 43 // Don't cast an object to an array, but rather an array of object. -
sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/inc/template-tags.php
r9989 r10214 10 10 namespace WordPressdotorg\Plugin_Directory\Theme; 11 11 12 use WordPressdotorg\Plugin_Directory\Plugin_Directory; 12 13 use WordPressdotorg\Plugin_Directory\Template; 13 14 use WordPressdotorg\Plugin_Directory\Tools; … … 260 261 } 261 262 263 function the_unconfirmed_releases_notice() { 264 $plugin = get_post(); 265 266 if ( ! $plugin->release_confirmation || ! current_user_can( 'plugin_admin_edit', $plugin ) ) { 267 return; 268 } 269 270 $confirmations_required = $plugin->release_confirmation; 271 $releases = Plugin_Directory::get_releases( $plugin ) ?: []; 272 $unconfirmed_releases = wp_list_filter( $confirmed_releases, [ 'confirmed' => false ] ); 273 274 if ( ! $unconfirmed_releases ) { 275 return; 276 } 277 278 printf( 279 '<div class="plugin-notice notice notice-info notice-alt"><p>%s</p></div>', 280 sprintf( 281 __( 'This plugin has <a href="%s">a pending release that requires confirmation</a>.', 'wporg-plugins' ), 282 home_url( '/developers/releases/' ) // TODO: Hardcoded URL. 283 ) 284 ); 285 } 286 262 287 /** 263 288 * Display the ADVANCED Zone. … … 346 371 347 372 echo '<div class="plugin-notice notice notice-error notice-alt"><p>' . esc_html__( 'These features often cannot be undone without intervention. Please do not attempt to use them unless you are absolutely certain. When in doubt, contact the plugins team for assistance.', 'wporg-plugins' ) . '</p></div>'; 373 374 // Output the Release Confirmation form. 375 the_plugin_release_confirmation_form(); 348 376 349 377 // Output the transfer form. … … 453 481 454 482 } 483 484 function the_plugin_release_confirmation_form() { 485 $post = get_post(); 486 487 // Temporary: Plugin Reviewers only. 488 if ( ! current_user_can( 'edit_post', $post ) ) { 489 return; 490 } 491 492 if ( 493 ! current_user_can( 'plugin_admin_edit', $post ) || 494 'publish' != $post->post_status 495 ) { 496 return; 497 } 498 499 $confirmations_required = $post->release_confirmation; 500 501 echo '<h4>' . esc_html__( 'Release Confirmation', 'wporg-plugins' ) . '</h4>'; 502 if ( $confirmations_required ) { 503 echo '<p>' . __( 'Release confirmations for this plugin are <strong>enabled</strong>.', 'wporg-plugins' ) . '</p>'; 504 } else { 505 echo '<p>' . __( 'Release confirmations for this plugin are <strong>disabled</strong>', 'wporg-plugins' ) . '</p>'; 506 } 507 echo '<p>' . esc_html__( 'All future releases will require email confirmation before being made available. This increases security and ensures that plugin releases are only made when intended.', 'wporg-plugins' ) . '</p>'; 508 509 if ( ! $confirmations_required && 'trunk' === $post->stable_tag ) { 510 echo '<div class="plugin-notice notice notice-warning notice-alt"><p>'; 511 _e( "Release confirmations currently require tagged releases, as you're releasing from trunk they cannot be enabled.", 'wporg-plugins' ); 512 echo '</p></div>'; 513 514 } else if ( ! $confirmations_required ) { 515 echo '<div class="plugin-notice notice notice-warning notice-alt"><p>'; 516 _e( '<strong>Warning:</strong> Enabling release confirmations is intended to be a <em>permanent</em> action. There is no way to disable this without contacting the plugins team.', 'wporg-plugins' ); 517 echo '</p></div>'; 518 519 echo '<form method="POST" action="' . esc_url( Template::get_enable_release_confirmation_link() ) . '" onsubmit="return confirm( jQuery(this).prev(\'.notice\').text() );">'; 520 echo '<p><input class="button" type="submit" value="' . esc_attr__( 'I understand, please enable release confirmations.', 'wporg-plugins' ) . '" /></p>'; 521 echo '</form>'; 522 523 } else { 524 /* translators: 1: plugins@wordpress.org */ 525 echo '<p>' . sprintf( __( 'To disable release confirmations, please contact the plugins team by emailing %s.', 'wporg-plugins' ), 'plugins@wordpress.org' ) . '</p>'; 526 } 527 } -
sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/template-parts/plugin-single.php
r9680 r10214 26 26 <header class="plugin-header"> 27 27 <?php the_active_plugin_notice(); ?> 28 <?php the_unconfirmed_releases_notice(); ?> 28 29 29 30 <div class="entry-thumbnail">
Note: See TracChangeset
for help on using the changeset viewer.