[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-includes/l10n/ -> class-wp-translation-file.php (source)

   1  <?php
   2  /**
   3   * I18N: WP_Translation_File class.
   4   *
   5   * @package WordPress
   6   * @subpackage I18N
   7   * @since 6.5.0
   8   */
   9  
  10  /**
  11   * Class WP_Translation_File.
  12   *
  13   * @since 6.5.0
  14   */
  15  abstract class WP_Translation_File {
  16      /**
  17       * List of headers.
  18       *
  19       * @since 6.5.0
  20       * @var array<string, string>
  21       */
  22      protected $headers = array();
  23  
  24      /**
  25       * Whether file has been parsed.
  26       *
  27       * @since 6.5.0
  28       * @var bool
  29       */
  30      protected $parsed = false;
  31  
  32      /**
  33       * Error information.
  34       *
  35       * @since 6.5.0
  36       * @var string|null Error message or null if no error.
  37       */
  38      protected $error;
  39  
  40      /**
  41       * File name.
  42       *
  43       * @since 6.5.0
  44       * @var string
  45       */
  46      protected $file = '';
  47  
  48      /**
  49       * Translation entries.
  50       *
  51       * @since 6.5.0
  52       * @var array<string, string>
  53       */
  54      protected $entries = array();
  55  
  56      /**
  57       * Plural forms function.
  58       *
  59       * @since 6.5.0
  60       * @var callable|null Plural forms.
  61       */
  62      protected $plural_forms = null;
  63  
  64      /**
  65       * Constructor.
  66       *
  67       * @since 6.5.0
  68       *
  69       * @param string $file File to load.
  70       */
  71  	protected function __construct( string $file ) {
  72          $this->file = $file;
  73      }
  74  
  75      /**
  76       * Creates a new WP_Translation_File instance for a given file.
  77       *
  78       * @since 6.5.0
  79       *
  80       * @param string      $file     File name.
  81       * @param string|null $filetype Optional. File type. Default inferred from file name.
  82       * @return false|WP_Translation_File
  83       */
  84  	public static function create( string $file, ?string $filetype = null ) {
  85          if ( ! is_readable( $file ) ) {
  86              return false;
  87          }
  88  
  89          if ( null === $filetype ) {
  90              $pos = strrpos( $file, '.' );
  91              if ( false !== $pos ) {
  92                  $filetype = substr( $file, $pos + 1 );
  93              }
  94          }
  95  
  96          switch ( $filetype ) {
  97              case 'mo':
  98                  return new WP_Translation_File_MO( $file );
  99              case 'php':
 100                  return new WP_Translation_File_PHP( $file );
 101              default:
 102                  return false;
 103          }
 104      }
 105  
 106      /**
 107       * Creates a new WP_Translation_File instance for a given file.
 108       *
 109       * @since 6.5.0
 110       *
 111       * @param string $file     Source file name.
 112       * @param string $filetype Desired target file type.
 113       * @return string|false Transformed translation file contents on success, false otherwise.
 114       */
 115  	public static function transform( string $file, string $filetype ) {
 116          $source = self::create( $file );
 117  
 118          if ( false === $source ) {
 119              return false;
 120          }
 121  
 122          switch ( $filetype ) {
 123              case 'mo':
 124                  $destination = new WP_Translation_File_MO( '' );
 125                  break;
 126              case 'php':
 127                  $destination = new WP_Translation_File_PHP( '' );
 128                  break;
 129              default:
 130                  return false;
 131          }
 132  
 133          $success = $destination->import( $source );
 134  
 135          if ( ! $success ) {
 136              return false;
 137          }
 138  
 139          return $destination->export();
 140      }
 141  
 142      /**
 143       * Returns all headers.
 144       *
 145       * @since 6.5.0
 146       *
 147       * @return array<string, string> Headers.
 148       */
 149  	public function headers(): array {
 150          if ( ! $this->parsed ) {
 151              $this->parse_file();
 152          }
 153          return $this->headers;
 154      }
 155  
 156      /**
 157       * Returns all entries.
 158       *
 159       * @since 6.5.0
 160       *
 161       * @return array<string, string[]> Entries.
 162       */
 163  	public function entries(): array {
 164          if ( ! $this->parsed ) {
 165              $this->parse_file();
 166          }
 167  
 168          return $this->entries;
 169      }
 170  
 171      /**
 172       * Returns the current error information.
 173       *
 174       * @since 6.5.0
 175       *
 176       * @return string|null Error message or null if no error.
 177       */
 178  	public function error() {
 179          return $this->error;
 180      }
 181  
 182      /**
 183       * Returns the file name.
 184       *
 185       * @since 6.5.0
 186       *
 187       * @return string File name.
 188       */
 189  	public function get_file(): string {
 190          return $this->file;
 191      }
 192  
 193      /**
 194       * Translates a given string.
 195       *
 196       * @since 6.5.0
 197       *
 198       * @param string $text String to translate.
 199       * @return false|string Translation(s) on success, false otherwise.
 200       */
 201  	public function translate( string $text ) {
 202          if ( ! $this->parsed ) {
 203              $this->parse_file();
 204          }
 205  
 206          return $this->entries[ $text ] ?? false;
 207      }
 208  
 209      /**
 210       * Returns the plural form for a given number.
 211       *
 212       * @since 6.5.0
 213       *
 214       * @param int $number Count.
 215       * @return int Plural form.
 216       */
 217  	public function get_plural_form( int $number ): int {
 218          if ( ! $this->parsed ) {
 219              $this->parse_file();
 220          }
 221  
 222          if ( null === $this->plural_forms && isset( $this->headers['plural-forms'] ) ) {
 223              $expression         = $this->get_plural_expression_from_header( $this->headers['plural-forms'] );
 224              $this->plural_forms = $this->make_plural_form_function( $expression );
 225          }
 226  
 227          if ( is_callable( $this->plural_forms ) ) {
 228              /**
 229               * Plural form.
 230               *
 231               * @var int $result Plural form.
 232               */
 233              $result = call_user_func( $this->plural_forms, $number );
 234  
 235              return $result;
 236          }
 237  
 238          // Default plural form matches English, only "One" is considered singular.
 239          return ( 1 === $number ? 0 : 1 );
 240      }
 241  
 242      /**
 243       * Returns the plural forms expression as a tuple.
 244       *
 245       * @since 6.5.0
 246       *
 247       * @param string $header Plural-Forms header string.
 248       * @return string Plural forms expression.
 249       */
 250  	protected function get_plural_expression_from_header( string $header ): string {
 251          if ( preg_match( '/^\s*nplurals\s*=\s*(\d+)\s*;\s+plural\s*=\s*(.+)$/', $header, $matches ) ) {
 252              return trim( $matches[2] );
 253          }
 254  
 255          return 'n != 1';
 256      }
 257  
 258      /**
 259       * Makes a function, which will return the right translation index, according to the
 260       * plural forms header.
 261       *
 262       * @since 6.5.0
 263       *
 264       * @param string $expression Plural form expression.
 265       * @return callable(int $num): int Plural forms function.
 266       */
 267  	protected function make_plural_form_function( string $expression ): callable {
 268          try {
 269              $handler = new Plural_Forms( rtrim( $expression, ';' ) );
 270              return array( $handler, 'get' );
 271          } catch ( Exception $e ) {
 272              // Fall back to default plural-form function.
 273              return $this->make_plural_form_function( 'n != 1' );
 274          }
 275      }
 276  
 277      /**
 278       * Imports translations from another file.
 279       *
 280       * @since 6.5.0
 281       *
 282       * @param WP_Translation_File $source Source file.
 283       * @return bool True on success, false otherwise.
 284       */
 285  	protected function import( WP_Translation_File $source ): bool {
 286          if ( null !== $source->error() ) {
 287              return false;
 288          }
 289  
 290          $this->headers = $source->headers();
 291          $this->entries = $source->entries();
 292          $this->error   = $source->error();
 293  
 294          return null === $this->error;
 295      }
 296  
 297      /**
 298       * Parses the file.
 299       *
 300       * @since 6.5.0
 301       */
 302      abstract protected function parse_file();
 303  
 304      /**
 305       * Exports translation contents as a string.
 306       *
 307       * @since 6.5.0
 308       *
 309       * @return string Translation file contents.
 310       */
 311      abstract public function export();
 312  }


Generated : Mon Apr 29 08:20:01 2024 Cross-referenced by PHPXref