makepot.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571
  1. <?php
  2. require_once dirname( __FILE__ ) . '/not-gettexted.php';
  3. require_once dirname( __FILE__ ) . '/pot-ext-meta.php';
  4. require_once dirname( __FILE__ ) . '/extract.php';
  5. if ( !defined( 'STDERR' ) ) {
  6. define( 'STDERR', fopen( 'php://stderr', 'w' ) );
  7. }
  8. class MakePOT {
  9. var $max_header_lines = 30;
  10. var $projects = array(
  11. 'generic',
  12. 'wp-frontend',
  13. 'wp-admin',
  14. 'wp-network-admin',
  15. 'wp-core',
  16. 'wp-ms',
  17. 'wp-tz',
  18. 'wp-plugin',
  19. 'wp-theme',
  20. 'bb',
  21. 'mu',
  22. 'bp',
  23. 'rosetta',
  24. 'wporg-bb-forums',
  25. );
  26. var $rules = array(
  27. '_' => array('string'),
  28. '__' => array('string'),
  29. '_e' => array('string'),
  30. '_c' => array('string'),
  31. '_n' => array('singular', 'plural'),
  32. '_n_noop' => array('singular', 'plural'),
  33. '_nc' => array('singular', 'plural'),
  34. '__ngettext' => array('singular', 'plural'),
  35. '__ngettext_noop' => array('singular', 'plural'),
  36. '_x' => array('string', 'context'),
  37. '_ex' => array('string', 'context'),
  38. '_nx' => array('singular', 'plural', null, 'context'),
  39. '_nx_noop' => array('singular', 'plural', 'context'),
  40. '_n_js' => array('singular', 'plural'),
  41. '_nx_js' => array('singular', 'plural', 'context'),
  42. 'esc_attr__' => array('string'),
  43. 'esc_html__' => array('string'),
  44. 'esc_attr_e' => array('string'),
  45. 'esc_html_e' => array('string'),
  46. 'esc_attr_x' => array('string', 'context'),
  47. 'esc_html_x' => array('string', 'context'),
  48. 'comments_number_link' => array('string', 'singular', 'plural'),
  49. );
  50. 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.*' );
  51. var $temp_files = array();
  52. var $meta = array(
  53. 'default' => array(
  54. 'from-code' => 'utf-8',
  55. 'msgid-bugs-address' => 'http://make.wordpress.org/polyglots',
  56. 'language' => 'php',
  57. 'add-comments' => 'translators',
  58. 'comments' => "Copyright (C) {year} {package-name}\nThis file is distributed under the same license as the {package-name} package.",
  59. ),
  60. 'generic' => array(),
  61. 'wp-frontend' => array(
  62. 'description' => 'Translation of frontend strings in WordPress {version}',
  63. 'copyright-holder' => 'WordPress',
  64. 'package-name' => 'WordPress',
  65. 'package-version' => '{version}',
  66. ),
  67. 'wp-admin' => array(
  68. 'description' => 'Translation of site admin strings in WordPress {version}',
  69. 'copyright-holder' => 'WordPress',
  70. 'package-name' => 'WordPress',
  71. 'package-version' => '{version}',
  72. ),
  73. 'wp-network-admin' => array(
  74. 'description' => 'Translation of network admin strings in WordPress {version}',
  75. 'copyright-holder' => 'WordPress',
  76. 'package-name' => 'WordPress',
  77. 'package-version' => '{version}',
  78. ),
  79. 'wp-core' => array(
  80. 'description' => 'Translation of WordPress {version}',
  81. 'copyright-holder' => 'WordPress',
  82. 'package-name' => 'WordPress',
  83. 'package-version' => '{version}',
  84. ),
  85. 'wp-ms' => array(
  86. 'description' => 'Translation of multisite strings in WordPress {version}',
  87. 'copyright-holder' => 'WordPress',
  88. 'package-name' => 'WordPress',
  89. 'package-version' => '{version}',
  90. ),
  91. 'wp-tz' => array(
  92. 'description' => 'Translation of timezone strings in WordPress {version}',
  93. 'copyright-holder' => 'WordPress',
  94. 'package-name' => 'WordPress',
  95. 'package-version' => '{version}',
  96. ),
  97. 'bb' => array(
  98. 'description' => 'Translation of bbPress',
  99. 'copyright-holder' => 'bbPress',
  100. 'package-name' => 'bbPress',
  101. ),
  102. 'wp-plugin' => array(
  103. 'description' => 'Translation of the WordPress plugin {name} {version} by {author}',
  104. 'msgid-bugs-address' => 'http://wordpress.org/support/plugin/{slug}',
  105. 'copyright-holder' => '{author}',
  106. 'package-name' => '{name}',
  107. 'package-version' => '{version}',
  108. ),
  109. 'wp-theme' => array(
  110. 'description' => 'Translation of the WordPress theme {name} {version} by {author}',
  111. 'msgid-bugs-address' => 'http://wordpress.org/support/theme/{slug}',
  112. 'copyright-holder' => '{author}',
  113. 'package-name' => '{name}',
  114. 'package-version' => '{version}',
  115. 'comments' => 'Copyright (C) {year} {author}\nThis file is distributed under the same license as the {package-name} package.',
  116. ),
  117. 'bp' => array(
  118. 'description' => 'Translation of BuddyPress',
  119. 'copyright-holder' => 'BuddyPress',
  120. 'package-name' => 'BuddyPress',
  121. ),
  122. 'glotpress' => array(
  123. 'description' => 'Translation of GlotPress',
  124. 'copyright-holder' => 'GlotPress',
  125. 'package-name' => 'GlotPress',
  126. ),
  127. 'wporg-bb-forums' => array(
  128. 'description' => 'WordPress.org International Forums',
  129. 'copyright-holder' => 'WordPress',
  130. 'package-name' => 'WordPress.org International Forums',
  131. ),
  132. 'rosetta' => array(
  133. 'description' => 'Rosetta (.wordpress.org locale sites)',
  134. 'copyright-holder' => 'WordPress',
  135. 'package-name' => 'Rosetta',
  136. ),
  137. );
  138. function __construct($deprecated = true) {
  139. $this->extractor = new StringExtractor( $this->rules );
  140. }
  141. function __destruct() {
  142. foreach ( $this->temp_files as $temp_file )
  143. unlink( $temp_file );
  144. }
  145. function tempnam( $file ) {
  146. $tempnam = tempnam( sys_get_temp_dir(), $file );
  147. $this->temp_files[] = $tempnam;
  148. return $tempnam;
  149. }
  150. function realpath_missing($path) {
  151. return realpath(dirname($path)).DIRECTORY_SEPARATOR.basename($path);
  152. }
  153. function xgettext($project, $dir, $output_file, $placeholders = array(), $excludes = array(), $includes = array()) {
  154. $meta = array_merge( $this->meta['default'], $this->meta[$project] );
  155. $placeholders = array_merge( $meta, $placeholders );
  156. $meta['output'] = $this->realpath_missing( $output_file );
  157. $placeholders['year'] = date( 'Y' );
  158. $placeholder_keys = array_map( create_function( '$x', 'return "{".$x."}";' ), array_keys( $placeholders ) );
  159. $placeholder_values = array_values( $placeholders );
  160. foreach($meta as $key => $value) {
  161. $meta[$key] = str_replace($placeholder_keys, $placeholder_values, $value);
  162. }
  163. $originals = $this->extractor->extract_from_directory( $dir, $excludes, $includes );
  164. $pot = new PO;
  165. $pot->entries = $originals->entries;
  166. $pot->set_header( 'Project-Id-Version', $meta['package-name'].' '.$meta['package-version'] );
  167. $pot->set_header( 'Report-Msgid-Bugs-To', $meta['msgid-bugs-address'] );
  168. $pot->set_header( 'POT-Creation-Date', gmdate( 'Y-m-d H:i:s+00:00' ) );
  169. $pot->set_header( 'MIME-Version', '1.0' );
  170. $pot->set_header( 'Content-Type', 'text/plain; charset=UTF-8' );
  171. $pot->set_header( 'Content-Transfer-Encoding', '8bit' );
  172. $pot->set_header( 'PO-Revision-Date', date( 'Y') . '-MO-DA HO:MI+ZONE' );
  173. $pot->set_header( 'Last-Translator', 'FULL NAME <EMAIL@ADDRESS>' );
  174. $pot->set_header( 'Language-Team', 'LANGUAGE <LL@li.org>' );
  175. $pot->set_comment_before_headers( $meta['comments'] );
  176. $pot->export_to_file( $output_file );
  177. return true;
  178. }
  179. function wp_generic($dir, $args) {
  180. $defaults = array(
  181. 'project' => 'wp-core',
  182. 'output' => null,
  183. 'default_output' => 'wordpress.pot',
  184. 'includes' => array(),
  185. 'excludes' => array_merge(
  186. array('wp-admin/includes/continents-cities\.php', 'wp-content/themes/twenty.*', ),
  187. $this->ms_files
  188. ),
  189. 'extract_not_gettexted' => false,
  190. 'not_gettexted_files_filter' => false,
  191. );
  192. $args = array_merge( $defaults, $args );
  193. extract( $args );
  194. $placeholders = array();
  195. if ( $wp_version = $this->wp_version( $dir ) )
  196. $placeholders['version'] = $wp_version;
  197. else
  198. return false;
  199. $output = is_null( $output )? $default_output : $output;
  200. $res = $this->xgettext( $project, $dir, $output, $placeholders, $excludes, $includes );
  201. if ( !$res ) return false;
  202. if ( $extract_not_gettexted ) {
  203. $old_dir = getcwd();
  204. $output = realpath( $output );
  205. chdir( $dir );
  206. $php_files = NotGettexted::list_php_files('.');
  207. $php_files = array_filter( $php_files, $not_gettexted_files_filter );
  208. $not_gettexted = new NotGettexted;
  209. $res = $not_gettexted->command_extract( $output, $php_files );
  210. chdir( $old_dir );
  211. /* Adding non-gettexted strings can repeat some phrases */
  212. $output_shell = escapeshellarg( $output );
  213. system( "msguniq --use-first $output_shell -o $output_shell" );
  214. }
  215. return $res;
  216. }
  217. function wp_core($dir, $output) {
  218. if ( file_exists( "$dir/wp-admin/user/about.php" ) ) return false;
  219. return $this->wp_generic( $dir, array(
  220. 'project' => 'wp-core', 'output' => $output,
  221. 'extract_not_gettexted' => true,
  222. 'not_gettexted_files_filter' => array( $this, 'is_not_ms_file' ),
  223. ) );
  224. }
  225. function wp_frontend($dir, $output) {
  226. if ( ! file_exists( "$dir/wp-admin/user/about.php" ) ) return false;
  227. return $this->wp_generic( $dir, array(
  228. 'project' => 'wp-frontend', 'output' => $output,
  229. 'includes' => array(), 'excludes' => array( 'wp-admin/.*', 'wp-content/themes/.*' ),
  230. 'default_output' => 'wordpress.pot',
  231. ) );
  232. }
  233. function wp_admin($dir, $output) {
  234. if ( ! file_exists( "$dir/wp-admin/user/about.php" ) ) return false;
  235. $frontend_pot = $this->tempnam( 'frontend.pot' );
  236. if ( false === $frontend_pot ) return false;
  237. $frontend_result = $this->wp_frontend( $dir, $frontend_pot );
  238. if ( ! $frontend_result )
  239. return false;
  240. $result = $this->wp_generic( $dir, array(
  241. 'project' => 'wp-admin', 'output' => $output,
  242. 'includes' => array( 'wp-admin/.*' ), 'excludes' => array( 'wp-admin/includes/continents-cities\.php', 'wp-admin/network/.*', 'wp-admin/network.php' ),
  243. 'default_output' => 'wordpress-admin.pot',
  244. ) );
  245. if ( ! $result )
  246. return false;
  247. $potextmeta = new PotExtMeta;
  248. $result = $potextmeta->append( "$dir/wp-content/plugins/akismet/akismet.php", $output );
  249. if ( ! $result )
  250. return false;
  251. $result = $potextmeta->append( "$dir/wp-content/plugins/hello.php", $output );
  252. if ( ! $result )
  253. return false;
  254. /* Adding non-gettexted strings can repeat some phrases */
  255. $output_shell = escapeshellarg($output);
  256. system("msguniq $output_shell -o $output_shell");
  257. $common_pot = $this->tempnam( 'common.pot' );
  258. if ( ! $common_pot )
  259. return false;
  260. $admin_pot = realpath( is_null( $output ) ? 'wordpress-admin.pot' : $output );
  261. system( "msgcat --more-than=1 --use-first $frontend_pot $admin_pot > $common_pot" );
  262. system( "msgcat -u --use-first $admin_pot $common_pot -o $admin_pot" );
  263. return true;
  264. }
  265. function wp_network_admin($dir, $output) {
  266. if ( ! file_exists( "$dir/wp-admin/user/about.php" ) ) return false;
  267. $frontend_pot = $this->tempnam( 'frontend.pot' );
  268. if ( false === $frontend_pot ) return false;
  269. $frontend_result = $this->wp_frontend( $dir, $frontend_pot );
  270. if ( ! $frontend_result )
  271. return false;
  272. $admin_pot = $this->tempnam( 'admin.pot' );
  273. if ( false === $admin_pot ) return false;
  274. $admin_result = $this->wp_admin( $dir, $admin_pot );
  275. if ( ! $admin_result )
  276. return false;
  277. $result = $this->wp_generic( $dir, array(
  278. 'project' => 'wp-network-admin', 'output' => $output,
  279. 'includes' => array( 'wp-admin/network/.*', 'wp-admin/network.php' ), 'excludes' => array(),
  280. 'default_output' => 'wordpress-admin-network.pot',
  281. ) );
  282. if ( ! $result ) {
  283. return false;
  284. }
  285. $common_pot = $this->tempnam( 'common.pot' );
  286. if ( ! $common_pot )
  287. return false;
  288. $net_admin_pot = realpath( is_null( $output ) ? 'wordpress-network-admin.pot' : $output );
  289. system( "msgcat --more-than=1 --use-first $frontend_pot $admin_pot $net_admin_pot > $common_pot" );
  290. system( "msgcat -u --use-first $net_admin_pot $common_pot -o $net_admin_pot" );
  291. return true;
  292. }
  293. function wp_ms($dir, $output) {
  294. if ( file_exists( "$dir/wp-admin/user/about.php" ) ) return false;
  295. if ( !is_file("$dir/wp-admin/ms-users.php") ) return false;
  296. $core_pot = $this->tempnam( 'wordpress.pot' );
  297. if ( false === $core_pot ) return false;
  298. $core_result = $this->wp_core( $dir, $core_pot );
  299. if ( ! $core_result )
  300. return false;
  301. $ms_result = $this->wp_generic( $dir, array(
  302. 'project' => 'wp-ms', 'output' => $output,
  303. 'includes' => $this->ms_files, 'excludes' => array(),
  304. 'default_output' => 'wordpress-ms.pot',
  305. 'extract_not_gettexted' => true,
  306. 'not_gettexted_files_filter' => array( $this, 'is_ms_file' ),
  307. ) );
  308. if ( !$ms_result ) {
  309. return false;
  310. }
  311. $common_pot = $this->tempnam( 'common.pot' );
  312. if ( ! $common_pot )
  313. return false;
  314. $ms_pot = realpath( is_null( $output )? 'wordpress-ms.pot' : $output );
  315. system( "msgcat --more-than=1 --use-first $core_pot $ms_pot > $common_pot" );
  316. system( "msgcat -u --use-first $ms_pot $common_pot -o $ms_pot" );
  317. return true;
  318. }
  319. function wp_tz($dir, $output) {
  320. $continents_path = 'wp-admin/includes/continents-cities.php';
  321. if ( !file_exists( "$dir/$continents_path" ) ) return false;
  322. return $this->wp_generic( $dir, array(
  323. 'project' => 'wp-tz', 'output' => $output,
  324. 'includes' => array($continents_path), 'excludes' => array(),
  325. 'default_output' => 'wordpress-continents-cities.pot',
  326. ) );
  327. }
  328. function wp_version($dir) {
  329. $version_php = $dir.'/wp-includes/version.php';
  330. if ( !is_readable( $version_php ) ) return false;
  331. return preg_match( '/\$wp_version\s*=\s*\'(.*?)\';/', file_get_contents( $version_php ), $matches )? $matches[1] : false;
  332. }
  333. function mu($dir, $output) {
  334. $placeholders = array();
  335. if (preg_match('/\$wpmu_version\s*=\s*\'(.*?)\';/', file_get_contents($dir.'/wp-includes/version.php'), $matches)) {
  336. $placeholders['version'] = $matches[1];
  337. }
  338. $output = is_null($output)? 'wordpress.pot' : $output;
  339. return $this->xgettext('wp', $dir, $output, $placeholders);
  340. }
  341. function bb($dir, $output) {
  342. $placeholders = array();
  343. $output = is_null($output)? 'bbpress.pot' : $output;
  344. return $this->xgettext('bb', $dir, $output, $placeholders);
  345. }
  346. function get_first_lines($filename, $lines = 30) {
  347. $extf = fopen($filename, 'r');
  348. if (!$extf) return false;
  349. $first_lines = '';
  350. foreach(range(1, $lines) as $x) {
  351. $line = fgets($extf);
  352. if (feof($extf)) break;
  353. if (false === $line) {
  354. return false;
  355. }
  356. $first_lines .= $line;
  357. }
  358. return $first_lines;
  359. }
  360. function get_addon_header($header, &$source) {
  361. if (preg_match('|'.$header.':(.*)$|mi', $source, $matches))
  362. return trim($matches[1]);
  363. else
  364. return false;
  365. }
  366. function generic($dir, $output) {
  367. $output = is_null($output)? "generic.pot" : $output;
  368. return $this->xgettext('generic', $dir, $output, array());
  369. }
  370. function guess_plugin_slug($dir) {
  371. if ('trunk' == basename($dir)) {
  372. $slug = basename(dirname($dir));
  373. } elseif (in_array(basename(dirname($dir)), array('branches', 'tags'))) {
  374. $slug = basename(dirname(dirname($dir)));
  375. } else {
  376. $slug = basename($dir);
  377. }
  378. return $slug;
  379. }
  380. function wp_plugin($dir, $output, $slug = null) {
  381. $placeholders = array();
  382. // guess plugin slug
  383. if (is_null($slug)) {
  384. $slug = $this->guess_plugin_slug($dir);
  385. }
  386. $main_file = $dir.'/'.$slug.'.php';
  387. $source = $this->get_first_lines($main_file, $this->max_header_lines);
  388. $placeholders['version'] = $this->get_addon_header('Version', $source);
  389. $placeholders['author'] = $this->get_addon_header('Author', $source);
  390. $placeholders['name'] = $this->get_addon_header('Plugin Name', $source);
  391. $placeholders['slug'] = $slug;
  392. $output = is_null($output)? "$slug.pot" : $output;
  393. $res = $this->xgettext('wp-plugin', $dir, $output, $placeholders);
  394. if (!$res) return false;
  395. $potextmeta = new PotExtMeta;
  396. $res = $potextmeta->append($main_file, $output);
  397. /* Adding non-gettexted strings can repeat some phrases */
  398. $output_shell = escapeshellarg($output);
  399. system("msguniq $output_shell -o $output_shell");
  400. return $res;
  401. }
  402. function wp_theme($dir, $output, $slug = null) {
  403. $placeholders = array();
  404. // guess plugin slug
  405. if (is_null($slug)) {
  406. $slug = $this->guess_plugin_slug($dir);
  407. }
  408. $main_file = $dir.'/style.css';
  409. $source = $this->get_first_lines($main_file, $this->max_header_lines);
  410. $placeholders['version'] = $this->get_addon_header('Version', $source);
  411. $placeholders['author'] = $this->get_addon_header('Author', $source);
  412. $placeholders['name'] = $this->get_addon_header('Theme Name', $source);
  413. $placeholders['slug'] = $slug;
  414. $license = $this->get_addon_header( 'License', $source );
  415. if ( $license )
  416. $this->meta['wp-theme']['comments'] = "Copyright (C) {year} {author}\nThis file is distributed under the {$license}.";
  417. else
  418. $this->meta['wp-theme']['comments'] = "Copyright (C) {year} {author}\nThis file is distributed under the same license as the {package-name} package.";
  419. $output = is_null($output)? "$slug.pot" : $output;
  420. $res = $this->xgettext('wp-theme', $dir, $output, $placeholders);
  421. if (! $res )
  422. return false;
  423. $potextmeta = new PotExtMeta;
  424. $res = $potextmeta->append( $main_file, $output, array( 'Theme Name', 'Theme URI', 'Description', 'Author', 'Author URI' ) );
  425. if ( ! $res )
  426. return false;
  427. // If we're dealing with a pre-3.4 default theme, don't extract page templates before 3.4.
  428. $extract_templates = ! in_array( $slug, array( 'twentyten', 'twentyeleven', 'default', 'classic' ) );
  429. if ( ! $extract_templates ) {
  430. $wp_dir = dirname( dirname( dirname( $dir ) ) );
  431. $extract_templates = file_exists( "$wp_dir/wp-admin/user/about.php" ) || ! file_exists( "$wp_dir/wp-load.php" );
  432. }
  433. if ( $extract_templates ) {
  434. $res = $potextmeta->append( $dir, $output, array( 'Template Name' ) );
  435. if ( ! $res )
  436. return false;
  437. $files = scandir( $dir );
  438. foreach ( $files as $file ) {
  439. if ( '.' == $file[0] || 'CVS' == $file )
  440. continue;
  441. if ( is_dir( $dir . '/' . $file ) ) {
  442. $res = $potextmeta->append( $dir . '/' . $file, $output, array( 'Template Name' ) );
  443. if ( ! $res )
  444. return false;
  445. }
  446. }
  447. }
  448. /* Adding non-gettexted strings can repeat some phrases */
  449. $output_shell = escapeshellarg($output);
  450. system("msguniq $output_shell -o $output_shell");
  451. return $res;
  452. }
  453. function bp($dir, $output) {
  454. $output = is_null($output)? "buddypress.pot" : $output;
  455. return $this->xgettext('bp', $dir, $output, array(), array('bp-forums/bbpress/.*'));
  456. }
  457. function glotpress( $dir, $output ) {
  458. $output = is_null( $output ) ? "glotpress.pot" : $output;
  459. return $this->xgettext( 'glotpress', $dir, $output );
  460. }
  461. function wporg_bb_forums( $dir, $output ) {
  462. $output = is_null( $output ) ? 'wporg.pot' : $output;
  463. return $this->xgettext( 'wporg-bb-forums', $dir, $output, array(), array(
  464. 'bb-plugins/elfakismet/.*',
  465. 'bb-plugins/support-forum/.*',
  466. ) );
  467. }
  468. function rosetta( $dir, $output ) {
  469. $output = is_null( $output )? 'rosetta.pot' : $output;
  470. return $this->xgettext( 'rosetta', $dir, $output, array(), array(), array(
  471. 'mu-plugins/rosetta.*\.php',
  472. 'mu-plugins/rosetta/[^/]+\.php',
  473. 'mu-plugins/rosetta/tmpl/.*\.php',
  474. 'themes/rosetta/.*\.php',
  475. ) );
  476. }
  477. function is_ms_file( $file_name ) {
  478. $is_ms_file = false;
  479. $prefix = substr( $file_name, 0, 2 ) === './'? '\./' : '';
  480. foreach( $this->ms_files as $ms_file )
  481. if ( preg_match( '|^'.$prefix.$ms_file.'$|', $file_name ) ) {
  482. $is_ms_file = true;
  483. break;
  484. }
  485. return $is_ms_file;
  486. }
  487. function is_not_ms_file( $file_name ) {
  488. return !$this->is_ms_file( $file_name );
  489. }
  490. }
  491. // run the CLI only if the file
  492. // wasn't included
  493. $included_files = get_included_files();
  494. if ($included_files[0] == __FILE__) {
  495. $makepot = new MakePOT;
  496. if ((3 == count($argv) || 4 == count($argv)) && in_array($method = str_replace('-', '_', $argv[1]), get_class_methods($makepot))) {
  497. $res = call_user_func(array($makepot, $method), realpath($argv[2]), isset($argv[3])? $argv[3] : null);
  498. if (false === $res) {
  499. fwrite(STDERR, "Couldn't generate POT file!\n");
  500. }
  501. } else {
  502. $usage = "Usage: php makepot.php PROJECT DIRECTORY [OUTPUT]\n\n";
  503. $usage .= "Generate POT file from the files in DIRECTORY [OUTPUT]\n";
  504. $usage .= "Available projects: ".implode(', ', $makepot->projects)."\n";
  505. fwrite(STDERR, $usage);
  506. exit(1);
  507. }
  508. }