Make WordPress Core

Changeset 36752


Ignore:
Timestamp:
02/28/2016 10:33:15 AM (9 years ago)
Author:
ocean90
Message:

i18n tools: Sync makepot.php with i18n.svn.

Changes: https://i18n.trac.wordpress.org/log/tools/trunk/makepot.php?rev=40331&stop_rev=24749

Fixes #34910, #34749.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tools/i18n/makepot.php

    r33448 r36752  
    88}
    99
     10/**
     11 * Class to create POT files for
     12 *  - WordPress 3.4+
     13 *  - WordPress plugins
     14 *  - WordPress themes
     15 *  - GlotPress (standalone)
     16 *  - WordPress.org projects (Rosetta, forums, directories)
     17 *  - WordCamp.org
     18 *
     19 * Support for older projects can be found in the legacy branch:
     20 * https://i18n.trac.wordpress.org/browser/tools/branches/legacy
     21 */
    1022class MakePOT {
    11     var $max_header_lines = 30;
    12 
    13     var $projects = array(
     23    private $max_header_lines = 30;
     24
     25    public $projects = array(
    1426        'generic',
    1527        'wp-frontend',
    1628        'wp-admin',
    1729        'wp-network-admin',
    18         'wp-core',
    19         'wp-ms',
    2030        'wp-tz',
    2131        'wp-plugin',
    2232        'wp-theme',
    23         'bb',
    24         'mu',
    25         'bp',
    2633        'glotpress',
    2734        'rosetta',
    2835        'wporg-bb-forums',
     36        'wporg-themes',
     37        'wporg-plugins',
     38        'wporg-forums',
     39        'wordcamporg',
    2940    );
    3041
    31     var $rules = array(
     42    public $rules = array(
    3243        '_' => array('string'),
    3344        '__' => array('string'),
     
    5465    );
    5566
    56     var $ms_files = array( 'ms-.*', '.*/ms-.*', '.*/my-.*', 'wp-activate\.php', 'wp-signup\.php', 'wp-admin/network\.php', 'wp-admin/includes/ms\.php', 'wp-admin/network/.*\.php', 'wp-admin/includes/class-wp-ms.*' );
    57 
    58     var $temp_files = array();
    59 
    60     var $meta = array(
     67    private $ms_files = array(
     68        'ms-.*', '.*/ms-.*', '.*/my-.*', 'wp-activate\.php', 'wp-signup\.php',
     69        'wp-admin/network\.php', 'wp-admin/network/.*\.php', 'wp-admin/includes/ms\.php',
     70        'wp-admin/includes/class-wp-ms.*', 'wp-admin/includes/network\.php',
     71    );
     72
     73    private $temp_files = array();
     74
     75    public $meta = array(
    6176        'default' => array(
    6277            'from-code' => 'utf-8',
     
    85100            'package-version' => '{version}',
    86101        ),
    87         'wp-core' => array(
    88             'description' => 'Translation of WordPress {version}',
     102        'wp-tz' => array(
     103            'description' => 'Translation of timezone strings in WordPress {version}',
    89104            'copyright-holder' => 'WordPress',
    90105            'package-name' => 'WordPress',
    91106            'package-version' => '{version}',
    92         ),
    93         'wp-ms' => array(
    94             'description' => 'Translation of multisite strings in WordPress {version}',
    95             'copyright-holder' => 'WordPress',
    96             'package-name' => 'WordPress',
    97             'package-version' => '{version}',
    98         ),
    99         'wp-tz' => array(
    100             'description' => 'Translation of timezone strings in WordPress {version}',
    101             'copyright-holder' => 'WordPress',
    102             'package-name' => 'WordPress',
    103             'package-version' => '{version}',
    104         ),
    105         'bb' => array(
    106             'description' => 'Translation of bbPress',
    107             'copyright-holder' => 'bbPress',
    108             'package-name' => 'bbPress',
    109107        ),
    110108        'wp-plugin' => array(
     
    123121            'comments' => 'Copyright (C) {year} {author}\nThis file is distributed under the same license as the {package-name} package.',
    124122        ),
    125         'bp' => array(
    126             'description' => 'Translation of BuddyPress',
    127             'copyright-holder' => 'BuddyPress',
    128             'package-name' => 'BuddyPress',
    129         ),
    130123        'glotpress' => array(
    131124            'description' => 'Translation of GlotPress',
     
    138131            'package-name' => 'WordPress.org International Forums',
    139132        ),
     133        'wporg' => array(
     134            'description' => 'WordPress.org',
     135            'copyright-holder' => 'WordPress',
     136            'package-name' => 'WordPress.org',
     137        ),
     138        'wordcamporg' => array(
     139            'description' => 'WordCamp.org',
     140            'copyright-holder' => 'WordPress',
     141            'package-name' => 'WordCamp.org',
     142        ),
    140143        'rosetta' => array(
    141144            'description' => 'Rosetta (.wordpress.org locale sites)',
     
    145148    );
    146149
    147     function __construct($deprecated = true) {
     150    public function __construct($deprecated = true) {
    148151        $this->extractor = new StringExtractor( $this->rules );
    149152    }
    150153
    151     function __destruct() {
     154    public function __destruct() {
    152155        foreach ( $this->temp_files as $temp_file )
    153156            unlink( $temp_file );
    154157    }
    155158
    156     function tempnam( $file ) {
     159    private function tempnam( $file ) {
    157160        $tempnam = tempnam( sys_get_temp_dir(), $file );
    158161        $this->temp_files[] = $tempnam;
     
    160163    }
    161164
    162     function realpath_missing($path) {
     165    private function realpath_missing($path) {
    163166        return realpath(dirname($path)).DIRECTORY_SEPARATOR.basename($path);
    164167    }
    165168
    166     function xgettext($project, $dir, $output_file, $placeholders = array(), $excludes = array(), $includes = array()) {
     169    private function xgettext($project, $dir, $output_file, $placeholders = array(), $excludes = array(), $includes = array()) {
    167170        $meta = array_merge( $this->meta['default'], $this->meta[$project] );
    168171        $placeholders = array_merge( $meta, $placeholders );
     
    193196    }
    194197
    195     function wp_generic($dir, $args) {
     198    public function wp_generic($dir, $args) {
    196199        $defaults = array(
    197200            'project' => 'wp-core',
     
    200203            'includes' => array(),
    201204            'excludes' => array_merge(
    202                 array('wp-admin/includes/continents-cities\.php', 'wp-content/themes/twenty.*', ),
     205                array( 'wp-admin/includes/continents-cities\.php', 'wp-content/themes/twenty.*', ),
    203206                $this->ms_files
    204207            ),
     
    233236    }
    234237
    235     function wp_core($dir, $output) {
    236         if ( file_exists( "$dir/wp-admin/user/about.php" ) ) return false;
    237 
    238         return $this->wp_generic( $dir, array(
    239             'project' => 'wp-core', 'output' => $output,
    240             'extract_not_gettexted' => true,
    241             'not_gettexted_files_filter' => array( $this, 'is_not_ms_file' ),
    242         ) );
    243     }
    244 
    245     function wp_frontend( $dir, $output ) {
     238    public function wp_frontend( $dir, $output ) {
    246239        if ( ! file_exists( "$dir/wp-admin/user/about.php" ) ) {
    247240            return false;
     
    263256    }
    264257
    265     function wp_admin($dir, $output) {
    266         if ( ! file_exists( "$dir/wp-admin/user/about.php" ) ) {
    267             return false;
    268         }
    269 
     258    public function wp_admin($dir, $output) {
    270259        $frontend_pot = $this->tempnam( 'frontend.pot' );
    271260        if ( false === $frontend_pot ) {
     
    277266            return false;
    278267        }
     268
     269        $network_admin_files = $this->get_wp_network_admin_files( $dir );
    279270
    280271        $result = $this->wp_generic( $dir, array(
    281272            'project' => 'wp-admin', 'output' => $output,
    282273            'includes' => array( 'wp-admin/.*' ),
    283             'excludes' => array( 'wp-admin/includes/continents-cities\.php', 'wp-admin/network/.*', 'wp-admin/network.php' ),
     274            'excludes' => array_merge( array( 'wp-admin/includes/continents-cities\.php' ), $network_admin_files ),
    284275            'default_output' => 'wordpress-admin.pot',
    285276        ) );
     
    316307    }
    317308
    318     function wp_network_admin($dir, $output) {
     309    public function wp_network_admin($dir, $output) {
    319310        if ( ! file_exists( "$dir/wp-admin/user/about.php" ) ) return false;
    320311
     
    335326        $result = $this->wp_generic( $dir, array(
    336327            'project' => 'wp-network-admin', 'output' => $output,
    337             'includes' => array( 'wp-admin/network/.*', 'wp-admin/network.php' ),
     328            'includes' => $this->get_wp_network_admin_files( $dir ),
    338329            'excludes' => array(),
    339330            'default_output' => 'wordpress-admin-network.pot',
     
    354345    }
    355346
    356     function wp_ms($dir, $output) {
    357         if ( file_exists( "$dir/wp-admin/user/about.php" ) ) return false;
    358         if ( !is_file("$dir/wp-admin/ms-users.php") ) return false;
    359         $core_pot = $this->tempnam( 'wordpress.pot' );
    360         if ( false === $core_pot ) return false;
    361         $core_result = $this->wp_core( $dir, $core_pot );
    362         if ( ! $core_result )
    363             return false;
    364         $ms_result = $this->wp_generic( $dir, array(
    365             'project' => 'wp-ms', 'output' => $output,
    366             'includes' => $this->ms_files,
    367             'excludes' => array(),
    368             'default_output' => 'wordpress-ms.pot',
    369             'extract_not_gettexted' => true,
    370             'not_gettexted_files_filter' => array( $this, 'is_ms_file' ),
    371         ) );
    372         if ( !$ms_result ) {
    373             return false;
    374         }
    375         $common_pot = $this->tempnam( 'common.pot' );
    376         if ( ! $common_pot )
    377             return false;
    378         $ms_pot = realpath( is_null( $output )? 'wordpress-ms.pot' : $output );
    379         system( "msgcat --more-than=1 --use-first $core_pot $ms_pot > $common_pot" );
    380         system( "msgcat -u --use-first $ms_pot $common_pot -o $ms_pot" );
    381         return true;
    382     }
    383 
    384     function wp_tz($dir, $output) {
    385         $continents_path = 'wp-admin/includes/continents-cities.php';
    386         if ( !file_exists( "$dir/$continents_path" ) ) return false;
     347    private function get_wp_network_admin_files( $dir ) {
     348        $wp_version = $this->wp_version( $dir );
     349
     350        // https://core.trac.wordpress.org/ticket/19852
     351        $files = array( 'wp-admin/network/.*', 'wp-admin/network.php' );
     352
     353        // https://core.trac.wordpress.org/ticket/34910
     354        if ( version_compare( $wp_version, '4.5-beta', '>=' ) ) {
     355            $files = array_merge( $files, array(
     356                'wp-admin/includes/class-wp-ms.*',
     357                'wp-admin/includes/network.php',
     358            ) );
     359        }
     360
     361        return $files;
     362    }
     363
     364    public function wp_tz( $dir, $output ) {
    387365        return $this->wp_generic( $dir, array(
    388366            'project' => 'wp-tz', 'output' => $output,
    389             'includes' => array( $continents_path ),
     367            'includes' => array( 'wp-admin/includes/continents-cities\.php' ),
    390368            'excludes' => array(),
    391369            'default_output' => 'wordpress-continents-cities.pot',
     
    393371    }
    394372
    395     function wp_version($dir) {
     373    private function wp_version( $dir ) {
    396374        $version_php = $dir.'/wp-includes/version.php';
    397375        if ( !is_readable( $version_php ) ) return false;
     
    399377    }
    400378
    401 
    402     function mu($dir, $output) {
    403         $placeholders = array();
    404         if (preg_match('/\$wpmu_version\s*=\s*\'(.*?)\';/', file_get_contents($dir.'/wp-includes/version.php'), $matches)) {
    405             $placeholders['version'] = $matches[1];
    406         }
    407         $output = is_null($output)? 'wordpress.pot' : $output;
    408         return $this->xgettext('wp', $dir, $output, $placeholders);
    409     }
    410 
    411 
    412     function bb($dir, $output) {
    413         $placeholders = array();
    414         $output = is_null($output)? 'bbpress.pot' : $output;
    415         return $this->xgettext('bb', $dir, $output, $placeholders);
    416 
    417     }
    418 
    419     function get_first_lines($filename, $lines = 30) {
     379    public function get_first_lines($filename, $lines = 30) {
    420380        $extf = fopen($filename, 'r');
    421381        if (!$extf) return false;
     
    429389            $first_lines .= $line;
    430390        }
     391
     392        // PHP will close file handle, but we are good citizens.
     393        fclose( $extf );
     394
     395        // Make sure we catch CR-only line endings.
     396        $first_lines = str_replace( "\r", "\n", $first_lines );
     397
    431398        return $first_lines;
    432399    }
    433400
    434 
    435     function get_addon_header($header, &$source) {
    436         if (preg_match('|'.$header.':(.*)$|mi', $source, $matches))
    437             return trim($matches[1]);
    438         else
    439             return false;
    440     }
    441 
    442     function generic($dir, $output) {
     401    public function get_addon_header($header, &$source) {
     402        /*
     403         * A few things this needs to handle:
     404         * - 'Header: Value\n'
     405         * - '// Header: Value'
     406         * - '/* Header: Value * /'
     407         * - '<?php // Header: Value ?>'
     408         * - '<?php /* Header: Value * / $foo='bar'; ?>'
     409         */
     410        if ( preg_match( '/^(?:[ \t]*<\?php)?[ \t\/*#@]*' . preg_quote( $header, '/' ) . ':(.*)$/mi', $source, $matches ) ) {
     411            return $this->_cleanup_header_comment( $matches[1] );
     412        } else {
     413            return false;
     414        }
     415    }
     416
     417    /**
     418     * Removes any trailing closing comment / PHP tags from the header value
     419     */
     420    private function _cleanup_header_comment( $str ) {
     421        return trim( preg_replace( '/\s*(?:\*\/|\?>).*/', '', $str ) );
     422    }
     423
     424    public function generic($dir, $output) {
    443425        $output = is_null($output)? "generic.pot" : $output;
    444426        return $this->xgettext('generic', $dir, $output, array());
    445427    }
    446428
    447     function guess_plugin_slug($dir) {
     429    private function guess_plugin_slug($dir) {
    448430        if ('trunk' == basename($dir)) {
    449431            $slug = basename(dirname($dir));
     
    456438    }
    457439
    458     function wp_plugin($dir, $output, $slug = null) {
     440    public function wp_plugin( $dir, $output, $slug = null, $args = array() ) {
     441        $defaults = array(
     442            'excludes' => array(),
     443            'includes' => array(),
     444        );
     445        $args = array_merge( $defaults, $args );
    459446        $placeholders = array();
    460447        // guess plugin slug
     
    507494
    508495        $output = is_null($output)? "$slug.pot" : $output;
    509         $res = $this->xgettext('wp-plugin', $dir, $output, $placeholders);
     496        $res = $this->xgettext( 'wp-plugin', $dir, $output, $placeholders, $args['excludes'], $args['includes'] );
    510497        if (!$res) return false;
    511498        $potextmeta = new PotExtMeta;
     
    517504    }
    518505
    519     function wp_theme($dir, $output, $slug = null) {
     506    public function wp_theme($dir, $output, $slug = null) {
    520507        $placeholders = array();
    521508        // guess plugin slug
     
    572559    }
    573560
    574     function bp($dir, $output) {
    575         $output = is_null($output)? "buddypress.pot" : $output;
    576         return $this->xgettext('bp', $dir, $output, array(), array('bp-forums/bbpress/.*'));
    577     }
    578 
    579     function glotpress( $dir, $output ) {
     561    public function glotpress( $dir, $output ) {
    580562        $output = is_null( $output ) ? "glotpress.pot" : $output;
    581563        return $this->xgettext( 'glotpress', $dir, $output );
    582564    }
    583565
    584     function wporg_bb_forums( $dir, $output ) {
     566    public function wporg_bb_forums( $dir, $output ) {
    585567        $output = is_null( $output ) ? 'wporg.pot' : $output;
    586568        return $this->xgettext( 'wporg-bb-forums', $dir, $output, array(), array(
    587569            'bb-plugins/elfakismet/.*',
    588570            'bb-plugins/support-forum/.*',
    589         ) );
    590     }
    591 
    592     function rosetta( $dir, $output ) {
     571            'themes/.*',
     572        ) );
     573    }
     574
     575    public function wporg_themes( $dir, $output ) {
     576        $output = is_null( $output ) ? 'wporg-themes.pot' : $output;
     577        return $this->xgettext( 'wporg', $dir, $output, array(), array(), array(
     578            'plugins/theme-directory/.*',
     579            'themes/pub/wporg-themes/.*'
     580        ) );
     581    }
     582
     583    public function wporg_plugins( $dir, $output ) {
     584        $output = is_null( $output ) ? 'wporg-plugins.pot' : $output;
     585        return $this->xgettext( 'wporg', $dir, $output, array(), array(
     586            'plugins/svn-track/i18n-tools/.*'
     587            ), array(
     588            '.*\.php',
     589        ) );
     590    }
     591
     592    public function wporg_forums( $dir, $output ) {
     593        $output = is_null( $output ) ? 'wporg-forums.pot' : $output;
     594        return $this->xgettext( 'wporg', $dir, $output, array(), array(), array(
     595            '.*\.php',
     596        ) );
     597    }
     598
     599    public function wordcamporg( $dir, $output ) {
     600        $output = is_null( $output ) ? 'wordcamporg.pot' : $output;
     601        return $this->xgettext( 'wordcamporg', $dir, $output, array(), array(), array(
     602            '.*\.php',
     603        ) );
     604    }
     605
     606    public function rosetta( $dir, $output ) {
    593607        $output = is_null( $output )? 'rosetta.pot' : $output;
    594         return $this->xgettext( 'rosetta', $dir, $output, array(), array(), array(
     608        return $this->xgettext( 'rosetta', $dir, $output, array(), array(
     609            'mu-plugins/rosetta/i18n-tools/.*',
     610            'mu-plugins/rosetta/locales/.*',
     611            ), array(
    595612            'mu-plugins/(roles|showcase|downloads)/.*\.php',
     613            'mu-plugins/jetpack-settings.php',
    596614            'mu-plugins/rosetta.*\.php',
    597615            'mu-plugins/rosetta/[^/]+\.php',
     
    599617            'themes/rosetta/.*\.php',
    600618        ) );
    601     }
    602 
    603     function is_ms_file( $file_name ) {
    604         $is_ms_file = false;
    605         $prefix = substr( $file_name, 0, 2 ) === './'? '\./' : '';
    606         foreach( $this->ms_files as $ms_file )
    607             if ( preg_match( '|^'.$prefix.$ms_file.'$|', $file_name ) ) {
    608                 $is_ms_file = true;
    609                 break;
    610             }
    611         return $is_ms_file;
    612     }
    613 
    614     function is_not_ms_file( $file_name ) {
    615         return !$this->is_ms_file( $file_name );
    616619    }
    617620}
Note: See TracChangeset for help on using the changeset viewer.