Changeset 3164
- Timestamp:
- 05/18/2016 02:12:47 AM (9 years ago)
- Location:
- sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/bin/import-plugin.php
r2649 r3164 6 6 die(); 7 7 } 8 9 ob_start(); 8 10 9 11 $opts = getopt( '', array( 'url:', 'abspath:', 'plugin:' ) ); … … 50 52 try { 51 53 $importer = new CLI\Import; 52 $importer->import ( $plugin_slug );54 $importer->import_from_svn( $plugin_slug ); 53 55 echo "OK\n"; 54 56 } catch( \Exception $e ) { 55 57 echo "Failed.\n"; 56 fwrite( STDERR, " Plugin Import Failed: " . $e->getMessage() . "\n" );58 fwrite( STDERR, "[{$plugin_slug}] Plugin Import Failed: " . $e->getMessage() . "\n" ); 57 59 exit(1); 58 60 } -
sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/cli/class-import.php
r3129 r3164 7 7 use WordPressdotorg\Plugin_Directory\Tools\Filesystem; 8 8 use WordPressdotorg\Plugin_Directory\Tools\SVN; 9 use Exception; 9 10 10 11 /** … … 47 48 * @param string $plugin_slug The slug of the plugin to import. 48 49 */ 49 public function import( $plugin_slug ) { 50 public function import_from_svn( $plugin_slug ) { 51 global $wpdb; 52 50 53 $plugin = Plugin_Directory::get_plugin_post( $plugin_slug ); 51 54 if ( ! $plugin ) { 52 // TODO throw new \Exception( "Unknown Plugin" );55 // TODO throw new Exception( "Unknown Plugin" ); 53 56 } 54 57 55 58 $data = $this->export_and_parse_plugin( $plugin_slug ); 56 59 57 if ( ! $plugin ) { 58 global $wpdb; 59 // TODO: During development while the bbPress variant is still running, we'll pull details from it and allow importing of any plugin. 60 $author = $wpdb->get_var( $wpdb->prepare( 'SELECT topic_poster FROM ' . PLUGINS_TABLE_PREFIX . 'topics WHERE topic_slug = %s', $plugin_slug ) ); 61 if ( ! $author ) { 62 throw new \Exception( "Unknown Plugin" ); 63 } 60 // TODO: During development while the bbPress variant is still running, we'll pull details from it and allow importing of any plugin. 61 $topic = $wpdb->get_row( $wpdb->prepare( 'SELECT * FROM ' . PLUGINS_TABLE_PREFIX . 'topics WHERE topic_slug = %s', $plugin_slug ) ); 62 63 if ( ! $plugin && ! $topic ) { 64 throw new Exception( "Unknown Plugin" ); 65 } 66 67 // TODO: During development we're just going to import status from bbPress. 68 $status = 'publish'; 69 if ( 2 == $topic->topic_open ) { 70 $status = 'approved'; 71 } elseif ( 2 == $topic->forum_id ) { 72 $status = 'pending'; 73 } elseif ( 4 == $topic->forum_id || 'rejected-' == substr( $topic->topic_slug, 0, 9 ) ) { 74 $status = 'rejected'; 75 } elseif ( 1 == $topic->forum_id && 0 == $topic->topic_open ) { 76 $status = 'closed'; 77 } elseif ( 3 == $topic->topic_open ) { 78 $status = 'disabled'; 79 } 80 81 if ( ! $plugin ) { 64 82 $plugin = Plugin_Directory::create_plugin_post( array( 65 83 'slug' => $plugin_slug, 66 'status' => 'publish', // If we're importing it on the CLI, and it didn't exist, assume it's published 67 'author' => $author 84 'status' => $status, 85 'author' => $topic->topic_poster, 86 'post_date_gmt' => $topic->topic_start_time, 87 'post_date' => $topic->topic_start_time, 88 'post_modified' => $topic->topic_time, 89 'post_modified_gmt' => $topic->topic_time, 68 90 ) ); 69 91 } … … 72 94 $assets = $data['assets']; 73 95 $headers = $data['plugin_headers']; 96 $stable_tag = $data['stable_tag']; 74 97 $tagged_versions = $data['tagged_versions']; 75 98 76 99 $content = ''; 77 foreach ( $readme->sections as $section => $section_content ) { 78 $content .= "\n\n<!--section={$section}-->\n{$section_content}"; 100 if ( $readme->sections ) { 101 foreach ( $readme->sections as $section => $section_content ) { 102 $content .= "\n\n<!--section={$section}-->\n{$section_content}"; 103 } 104 } elseif ( !empty( $headers->Description ) ) { 105 $content = "<!--section=description-->\n{$headers->Description}"; 79 106 } 80 107 81 108 // Fallback to the plugin title if the readme didn't contain it. 82 $plugin->post_title = trim( $readme->name ) ?: strip_tags( $headers->Name ); 83 $plugin->post_content = trim( $content ); 84 $plugin->post_excerpt = trim( $readme->short_description ); 109 $plugin->post_title = trim( $readme->name ) ?: strip_tags( $headers->Name ) ?: $plugin->post_title; 110 $plugin->post_content = trim( $content ) ?: $plugin->post_content; 111 $plugin->post_excerpt = trim( $readme->short_description ) ?: $headers->Description ?: $plugin->post_excerpt; 112 113 $plugin->post_date = $topic->topic_start_time; 114 $plugin->post_date_gmt = $topic->topic_start_time; 115 $plugin->override_modified_date = true; 116 $plugin->post_modified = $topic->topic_time; 117 $plugin->post_modified_gmt = $topic->topic_time; 118 119 $plugin->post_status = $status; 120 if ( ! $plugin->post_title ) { 121 $plugin->post_title = $topic->topic_title; 122 } 85 123 86 124 // Bump last updated if the version has changed. 87 if ( $headers->Version != get_post_meta( $plugin->ID, 'version', true ) ) {125 if ( !isset( $headers->Version ) || $headers->Version != get_post_meta( $plugin->ID, 'version', true ) ) { 88 126 $plugin->post_modified = $plugin->post_modified_gmt = current_time( 'mysql' ); 89 127 } 90 128 129 add_filter( 'wp_insert_post_data', array( $this, 'filter_wp_insert_post_data' ), 10, 2 ); 91 130 wp_update_post( $plugin ); 131 remove_filter( 'wp_insert_post_data', array( $this, 'filter_wp_insert_post_data' ) ); 92 132 93 133 foreach ( $this->readme_fields as $readme_field ) { … … 96 136 continue; 97 137 } 98 update_post_meta( $plugin->ID, $readme_field, wp_slash( $readme->$readme_field ) ); 99 } 138 139 if ( 'stable_tag' == $readme_field ) { 140 // The stable_tag needs to come from the trunk readme at all times. 141 $value = $stable_tag; 142 } else { 143 $value = $readme->$readme_field; 144 } 145 146 update_post_meta( $plugin->ID, $readme_field, wp_slash( $value ) ); 147 } 148 100 149 foreach ( $this->plugin_headers as $plugin_header => $meta_field ) { 101 update_post_meta( $plugin->ID, $meta_field, wp_slash( $headers->$plugin_header) );150 update_post_meta( $plugin->ID, $meta_field, ( isset( $headers->$plugin_header ) ? wp_slash( $headers->$plugin_header ) : '' ) ); 102 151 } 103 152 … … 141 190 * 142 191 * @return array { 143 * 'readme', ' trunk_readme', 'tmp_dir', 'plugin_headers', 'assets'192 * 'readme', 'stable_tag', 'plugin_headers', 'assets', 'tagged_versions' 144 193 * } 145 194 */ … … 147 196 $tmp_dir = Filesystem::temp_directory( "process-{$plugin_slug}" ); 148 197 149 $svn_export = SVN::export( self::PLUGIN_SVN_BASE . "/{$plugin_slug}/trunk", $tmp_dir . '/trunk', array( 'ignore-externals' ) ); 150 if ( ! $svn_export['result'] || empty( $svn_export['revision'] ) ) { 151 throw new \Exception( "Could not create SVN export." . implode( ' ', reset( $svn_export['errors'] ) ) ); 152 } 153 $trunk_revision = $svn_export['revision']; 154 155 $trunk_readme = $this->find_readme_file( $tmp_dir . '/trunk' ); 156 if ( ! $trunk_readme ) { 157 throw new \Exception( "Could not locate a trunk readme" ); 158 } 159 $trunk_readme = new Readme_Parser( $trunk_readme ); 160 161 if ( $trunk_readme->stable_tag == 'trunk' || empty( $trunk_readme->stable_tag ) ) { 162 $readme = $trunk_readme; 163 $stable = 'trunk'; 164 $stable_revision = $trunk_revision; 198 // Find the trunk readme file, list remotely to avoid checking out the entire directory. 199 $trunk_files = SVN::ls( self::PLUGIN_SVN_BASE . "/{$plugin_slug}/trunk" ); 200 if ( ! $trunk_files ) { 201 throw new Exception( 'Plugin has no files in trunk.' ); 202 } 203 204 // A plugin historically doesn't have to have a readme. 205 $trunk_readme_files = preg_grep( '!^readme.(txt|md)$!i', $trunk_files ); 206 if ( $trunk_readme_files ) { 207 $trunk_readme_file = reset( $trunk_readme_files ); 208 foreach ( $trunk_readme_files as $f ) { 209 if ( '.txt' == strtolower( substr( $f, -4 ) ) ) { 210 $trunk_readme_file = $f; 211 break; 212 } 213 } 214 215 $trunk_readme_file = self::PLUGIN_SVN_BASE . "/{$plugin_slug}/trunk/{$trunk_readme_file}"; 216 $trunk_readme = new Readme_Parser( $trunk_readme_file ); 217 218 $stable_tag = $trunk_readme->stable_tag; 165 219 } else { 166 // There's a chance that the stable_tag will not actually exist, we have to fallback to trunk in those cases and avoid exiting here. 167 $stable_tag = preg_replace( '![^a-z0-9-_.]!i', '', $trunk_readme->stable_tag ); 168 $svn_export = SVN::export( self::PLUGIN_SVN_BASE . "/{$plugin_slug}/tags/{$stable_tag}", $tmp_dir . '/stable', array( 'ignore-externals' ) ); 169 170 $stable_readme = $svn_export['result'] ? $this->find_readme_file( $tmp_dir . '/stable' ) : false; 171 if ( $stable_readme ) { 172 $readme = $stable_readme = new Readme_Parser( $stable_readme ); 173 $stable = 'stable'; 174 $stable_revision = $svn_export['revision']; 220 $stable_tag = 'trunk'; 221 } 222 223 $exported = false; 224 if ( $stable_tag && 'trunk' != $stable_tag ) { 225 $svn_export = SVN::export( 226 self::PLUGIN_SVN_BASE . "/{$plugin_slug}/tags/{$stable_tag}", 227 $tmp_dir . '/export', 228 array( 229 'ignore-externals', 230 'depth' => 'files' 231 ) 232 ); 233 if ( $svn_export['result'] && false !== $this->find_readme_file( $tmp_dir . '/export' ) ) { 234 $exported = true; 175 235 } else { 176 // Trunk is stable! 177 $readme = $trunk_readme; 178 $stable = 'trunk'; 179 $stable_revision = $trunk_revision; 180 } 181 } 182 183 $plugin_headers = $this->find_plugin_headers( "$tmp_dir/$stable" ); 236 // Clear out any files that exist in the export. 237 Filesystem::rmdir( $tmp_dir . '/export' ); 238 } 239 } 240 if ( ! $exported ) { 241 $stable_tag = 'trunk'; 242 // Either stable_tag = trunk, or the stable_tag tag didn't exist. 243 $svn_export = SVN::export( 244 self::PLUGIN_SVN_BASE . "/{$plugin_slug}/trunk", 245 $tmp_dir . '/export', 246 array( 247 'ignore-externals', 248 'depth' => 'files' // Only export the root files, we don't need the rest to read the plugin headers/screenshots 249 ) 250 ); 251 if ( ! $svn_export['result'] || empty( $svn_export['revision'] ) ) { 252 throw new Exception( 'Could not create SVN export: ' . implode( ' ', reset( $svn_export['errors'] ) ) ); 253 } 254 } 255 256 // The readme may not actually exist, but that's okay. 257 $readme = $this->find_readme_file( $tmp_dir . '/export' ); 258 $readme = new Readme_Parser( $readme ); 259 260 // There must be valid plugin headers though. 261 $plugin_headers = $this->find_plugin_headers( "$tmp_dir/export" ); 262 if ( ! $plugin_headers ) { 263 throw new Exception( 'Could not find the plugin headers.' ); 264 } 184 265 185 266 // Now we look in the /assets/ folder for banners, screenshots, and icons. … … 201 282 } 202 283 203 $tagged_versions = SVN::ls( "https://plugins.svn.wordpress.org/{$plugin_slug}/tags/" ) ;284 $tagged_versions = SVN::ls( "https://plugins.svn.wordpress.org/{$plugin_slug}/tags/" ) ?: array(); 204 285 $tagged_versions = array_map( function( $item ) { 205 286 return rtrim( $item, '/' ); … … 207 288 208 289 // Find screenshots in the stable plugin folder (but don't overwrite /assets/) 209 foreach ( Filesystem::list_files( "$tmp_dir/ $stable/", false /* non-recursive */, '!^screenshot-\d+\.(jpeg|jpg|png|gif)$!' ) as $plugin_screenshot ) {290 foreach ( Filesystem::list_files( "$tmp_dir/export/", false /* non-recursive */, '!^screenshot-\d+\.(jpeg|jpg|png|gif)$!' ) as $plugin_screenshot ) { 210 291 $filename = basename( $plugin_screenshot ); 211 292 $screenshot_id = substr( $filename, strpos( $filename, '-' ) + 1 ); … … 219 300 $assets['screenshot'][ $filename ] = array( 220 301 'filename' => $filename, 221 'revision' => $s table_revision,302 'revision' => $svn_export['revision'], 222 303 'resolution' => $screenshot_id, 223 304 'location' => 'plugin', … … 225 306 } 226 307 227 return compact( 'readme', 'trunk_readme', 'tmp_dir', 'plugin_headers', 'assets', 'tagged_versions' ); 308 return compact( 'readme', 'stable_tag', 'tmp_dir', 'plugin_headers', 'assets', 'tagged_versions' ); 309 } 310 311 /** 312 * Filters `wp_insert_post()` to allow a custom modified date to be specified. 313 * 314 * @param array $data The data to be inserted into the database. 315 * @param array $postarr The raw data passed to `wp_insert_post()`. 316 * 317 * @return array The data to insert into the database. 318 */ 319 public function filter_wp_insert_post_data( $data, $postarr ) { 320 if ( !empty( $postarr['override_modified_date'] ) ) { 321 $data['post_modified'] = $postarr['post_modified']; 322 $data['post_modified_gmt'] = $postarr['post_modified_gmt']; 323 } 324 return $data; 228 325 } 229 326 … … 260 357 $files = Filesystem::list_files( $directory, false, '!\.php$!i' ); 261 358 359 if ( ! function_exists( 'get_plugin_data' ) ) { 360 require ABSPATH . 'wp-admin/includes/plugin.php'; 361 } 362 363 /* 364 * Sometimes plugins have multiple files which we detect as a plugin based on the headers. 365 * We'll return immediately if the file has a `Plugin Name:` header, otherwise 366 * simply return the last set of headers we come across. 367 */ 368 $possible_headers = false; 262 369 foreach ( $files as $file ) { 263 370 $data = get_plugin_data( $file, false, false ); 264 371 if ( array_filter( $data ) ) { 265 return (object) $data; 266 } 372 if ( $data['Name'] ) { 373 return (object) $data; 374 } else { 375 $possible_headers = (object) $data; 376 } 377 } 378 } 379 380 if ( $possible_headers ) { 381 return $possible_headers; 267 382 } 268 383
Note: See TracChangeset
for help on using the changeset viewer.