[ Index ]

PHP Cross Reference of YOURLS

title

Body

[close]

/includes/ -> functions-l10n.php (source)

   1  <?php
   2  /**
   3   * YOURLS Translation API
   4   *
   5   * YOURLS modification of a small subset from WordPress' Translation API implementation.
   6   * GPL License
   7   *
   8   * @package POMO
   9   * @subpackage i18n
  10   */
  11  
  12  /**
  13   * Load POMO files required to run library
  14   */
  15  use POMO\MO;
  16  use POMO\Translations\NOOPTranslations;
  17  
  18  /**
  19   * Gets the current locale.
  20   *
  21   * If the locale is set, then it will filter the locale in the 'get_locale' filter
  22   * hook and return the value.
  23   *
  24   * If the locale is not set already, then the YOURLS_LANG constant is used if it is
  25   * defined. Then it is filtered through the 'get_locale' filter hook and the value
  26   * for the locale global set and the locale is returned.
  27   *
  28   * The process to get the locale should only be done once, but the locale will
  29   * always be filtered using the 'get_locale' hook.
  30   *
  31   * @since 1.6
  32   *
  33   * @return string The locale of the YOURLS instance
  34   */
  35  function yourls_get_locale() {
  36      global $yourls_locale;
  37  
  38      if ( !isset( $yourls_locale ) ) {
  39          // YOURLS_LANG is defined in config.
  40          if ( defined( 'YOURLS_LANG' ) )
  41              $yourls_locale = YOURLS_LANG;
  42      }
  43  
  44      if ( !$yourls_locale )
  45          $yourls_locale = '';
  46  
  47      return yourls_apply_filter( 'get_locale', $yourls_locale );
  48  }
  49  
  50  /**
  51   * Retrieves the translation of $text. If there is no translation, or
  52   * the domain isn't loaded, the original text is returned.
  53   *
  54   * @see yourls__() Don't use yourls_translate() directly, use yourls__()
  55   * @since 1.6
  56   *
  57   * @param string $text Text to translate.
  58   * @param string $domain Domain to retrieve the translated text.
  59   * @return string Translated text
  60   */
  61  function yourls_translate( $text, $domain = 'default' ) {
  62      $translations = yourls_get_translations_for_domain( $domain );
  63      return yourls_apply_filter( 'translate', $translations->translate( $text ), $text, $domain );
  64  }
  65  
  66  /**
  67   * Retrieves the translation of $text with a given $context. If there is no translation, or
  68   * the domain isn't loaded, the original text is returned.
  69   *
  70   * Quite a few times, there will be collisions with similar translatable text
  71   * found in more than two places but with different translated context.
  72   *
  73   * By including the context in the pot file translators can translate the two
  74   * strings differently.
  75   *
  76   * @since 1.6
  77   * @param string $text Text to translate.
  78   * @param string $context Context.
  79   * @param string $domain Domain to retrieve the translated text.
  80   * @return string Translated text
  81   */
  82  function yourls_translate_with_context( $text, $context, $domain = 'default' ) {
  83      $translations = yourls_get_translations_for_domain( $domain );
  84      return yourls_apply_filter( 'translate_with_context', $translations->translate( $text, $context ), $text, $context, $domain );
  85  }
  86  
  87  /**
  88   * Retrieves the translation of $text. If there is no translation, or
  89   * the domain isn't loaded, the original text is returned.
  90   *
  91   * @see yourls_translate() An alias of yourls_translate()
  92   * @since 1.6
  93   *
  94   * @param string $text Text to translate
  95   * @param string $domain Optional. Domain to retrieve the translated text
  96   * @return string Translated text
  97   */
  98  function yourls__( $text, $domain = 'default' ) {
  99      return yourls_translate( $text, $domain );
 100  }
 101  
 102  /**
 103   * Return a translated sprintf() string (mix yourls__() and sprintf() in one func)
 104   *
 105   * Instead of doing sprintf( yourls__( 'string %s' ), $arg ) you can simply use:
 106   * yourls_s( 'string %s', $arg )
 107   * This function accepts an arbitrary number of arguments:
 108   * - first one will be the string to translate, eg "hello %s my name is %s"
 109   * - following ones will be the sprintf arguments, eg "world" and "Ozh"
 110   * - if there are more arguments passed than needed, the last one will be used as the translation domain
 111   *
 112   * @see sprintf()
 113   * @since 1.6
 114   *
 115   * @param mixed ...$pattern Text to translate, then $arg1: optional sprintf tokens, and $arg2: translation domain
 116   * @return string Translated text
 117   */
 118  function yourls_s( $pattern ) {
 119      // Get pattern and pattern arguments
 120      $args = func_get_args();
 121      // If yourls_s() called by yourls_se(), all arguments are wrapped in the same array key
 122      if( count( $args ) == 1 && is_array( $args[0] ) ) {
 123          $args = $args[0];
 124      }
 125      $pattern = $args[0];
 126  
 127      // get list of sprintf tokens (%s and such)
 128      $num_of_tokens = substr_count( $pattern, '%' ) - 2 * substr_count( $pattern, '%%' );
 129  
 130      $domain = 'default';
 131      // More arguments passed than needed for the sprintf? The last one will be the domain
 132      if( $num_of_tokens < ( count( $args ) - 1 ) ) {
 133          $domain = array_pop( $args );
 134      }
 135  
 136      // Translate text
 137      $args[0] = yourls__( $pattern, $domain );
 138  
 139      return call_user_func_array( 'sprintf', $args );
 140  }
 141  
 142  /**
 143   * Echo a translated sprintf() string (mix yourls__() and sprintf() in one func)
 144   *
 145   * Instead of doing printf( yourls__( 'string %s' ), $arg ) you can simply use:
 146   * yourls_se( 'string %s', $arg )
 147   * This function accepts an arbitrary number of arguments:
 148   * - first one will be the string to translate, eg "hello %s my name is %s"
 149   * - following ones will be the sprintf arguments, eg "world" and "Ozh"
 150   * - if there are more arguments passed than needed, the last one will be used as the translation domain
 151   *
 152   * @see yourls_s()
 153   * @see sprintf()
 154   * @since 1.6
 155   *
 156   * @param string ...$pattern Text to translate, then optional sprintf tokens, and optional translation domain
 157   * @return void Translated text
 158   */
 159  function yourls_se( $pattern ) {
 160      echo yourls_s( func_get_args() );
 161  }
 162  
 163  
 164  /**
 165   * Retrieves the translation of $text and escapes it for safe use in an attribute.
 166   * If there is no translation, or the domain isn't loaded, the original text is returned.
 167   *
 168   * @see yourls_translate() An alias of yourls_translate()
 169   * @see yourls_esc_attr()
 170   * @since 1.6
 171   *
 172   * @param string $text Text to translate
 173   * @param string $domain Optional. Domain to retrieve the translated text
 174   * @return string Translated text
 175   */
 176  function yourls_esc_attr__( $text, $domain = 'default' ) {
 177      return yourls_esc_attr( yourls_translate( $text, $domain ) );
 178  }
 179  
 180  /**
 181   * Retrieves the translation of $text and escapes it for safe use in HTML output.
 182   * If there is no translation, or the domain isn't loaded, the original text is returned.
 183   *
 184   * @see yourls_translate() An alias of yourls_translate()
 185   * @see yourls_esc_html()
 186   * @since 1.6
 187   *
 188   * @param string $text Text to translate
 189   * @param string $domain Optional. Domain to retrieve the translated text
 190   * @return string Translated text
 191   */
 192  function yourls_esc_html__( $text, $domain = 'default' ) {
 193      return yourls_esc_html( yourls_translate( $text, $domain ) );
 194  }
 195  
 196  /**
 197   * Displays the returned translated text from yourls_translate().
 198   *
 199   * @see yourls_translate() Echoes returned yourls_translate() string
 200   * @since 1.6
 201   *
 202   * @param string $text Text to translate
 203   * @param string $domain Optional. Domain to retrieve the translated text
 204   * @return void
 205   */
 206  function yourls_e( $text, $domain = 'default' ) {
 207      echo yourls_translate( $text, $domain );
 208  }
 209  
 210  /**
 211   * Displays translated text that has been escaped for safe use in an attribute.
 212   *
 213   * @see yourls_translate() Echoes returned yourls_translate() string
 214   * @see yourls_esc_attr()
 215   * @since 1.6
 216   *
 217   * @param string $text Text to translate
 218   * @param string $domain Optional. Domain to retrieve the translated text
 219   * @return void
 220   */
 221  function yourls_esc_attr_e( $text, $domain = 'default' ) {
 222      echo yourls_esc_attr( yourls_translate( $text, $domain ) );
 223  }
 224  
 225  /**
 226   * Displays translated text that has been escaped for safe use in HTML output.
 227   *
 228   * @see yourls_translate() Echoes returned yourls_translate() string
 229   * @see yourls_esc_html()
 230   * @since 1.6
 231   *
 232   * @param string $text Text to translate
 233   * @param string $domain Optional. Domain to retrieve the translated text
 234   * @return void
 235   */
 236  function yourls_esc_html_e( $text, $domain = 'default' ) {
 237      echo yourls_esc_html( yourls_translate( $text, $domain ) );
 238  }
 239  
 240  /**
 241   * Retrieve translated string with gettext context
 242   *
 243   * Quite a few times, there will be collisions with similar translatable text
 244   * found in more than two places but with different translated context.
 245   *
 246   * By including the context in the pot file translators can translate the two
 247   * strings differently.
 248   *
 249   * @since 1.6
 250   *
 251   * @param string $text Text to translate
 252   * @param string $context Context information for the translators
 253   * @param string $domain Optional. Domain to retrieve the translated text
 254   * @return string Translated context string
 255   */
 256  function yourls_x( $text, $context, $domain = 'default' ) {
 257      return yourls_translate_with_context( $text, $context, $domain );
 258  }
 259  
 260  /**
 261   * Displays translated string with gettext context
 262   *
 263   * @see yourls_x()
 264   * @since 1.7.1
 265   *
 266   * @param string $text Text to translate
 267   * @param string $context Context information for the translators
 268   * @param string $domain Optional. Domain to retrieve the translated text
 269   * @return void Echoes translated context string
 270   */
 271  function yourls_xe( $text, $context, $domain = 'default' ) {
 272      echo yourls_x( $text, $context, $domain );
 273  }
 274  
 275  
 276  /**
 277   * Return translated text, with context, that has been escaped for safe use in an attribute
 278   *
 279   * @see yourls_translate() Return returned yourls_translate() string
 280   * @see yourls_esc_attr()
 281   * @see yourls_x()
 282   * @since 1.6
 283   *
 284   * @param string   $single
 285   * @param string   $context
 286   * @param string   $domain Optional. Domain to retrieve the translated text
 287   * @return string
 288   */
 289  function yourls_esc_attr_x( $single, $context, $domain = 'default' ) {
 290      return yourls_esc_attr( yourls_translate_with_context( $single, $context, $domain ) );
 291  }
 292  
 293  /**
 294   * Return translated text, with context, that has been escaped for safe use in HTML output
 295   *
 296   * @see yourls_translate() Return returned yourls_translate() string
 297   * @see yourls_esc_attr()
 298   * @see yourls_x()
 299   * @since 1.6
 300   *
 301   * @param string   $single
 302   * @param string   $context
 303   * @param string   $domain Optional. Domain to retrieve the translated text
 304   * @return string
 305   */
 306  function yourls_esc_html_x( $single, $context, $domain = 'default' ) {
 307      return yourls_esc_html( yourls_translate_with_context( $single, $context, $domain ) );
 308  }
 309  
 310  /**
 311   * Retrieve the plural or single form based on the amount.
 312   *
 313   * If the domain is not set in the $yourls_l10n list, then a comparison will be made
 314   * and either $plural or $single parameters returned.
 315   *
 316   * If the domain does exist, then the parameters $single, $plural, and $number
 317   * will first be passed to the domain's ngettext method. Then it will be passed
 318   * to the 'translate_n' filter hook along with the same parameters. The expected
 319   * type will be a string.
 320   *
 321   * @since 1.6
 322   *
 323   * @param string $single The text that will be used if $number is 1
 324   * @param string $plural The text that will be used if $number is not 1
 325   * @param int $number The number to compare against to use either $single or $plural
 326   * @param string $domain Optional. The domain identifier the text should be retrieved in
 327   * @return string Either $single or $plural translated text
 328   */
 329  function yourls_n( $single, $plural, $number, $domain = 'default' ) {
 330      $translations = yourls_get_translations_for_domain( $domain );
 331      $translation = $translations->translate_plural( $single, $plural, $number );
 332      return yourls_apply_filter( 'translate_n', $translation, $single, $plural, $number, $domain );
 333  }
 334  
 335  /**
 336   * A hybrid of yourls_n() and yourls_x(). It supports contexts and plurals.
 337   *
 338   * @since 1.6
 339   * @see yourls_n()
 340   * @see yourls_x()
 341   *
 342   * @param string $single   The text that will be used if $number is 1
 343   * @param string $plural   The text that will be used if $number is not 1
 344   * @param int $number      The number to compare against to use either $single or $plural
 345   * @param string $context  Context information for the translators
 346   * @param string $domain   Optional. The domain identifier the text should be retrieved in
 347   * @return string          Either $single or $plural translated text
 348   */
 349  function yourls_nx($single, $plural, $number, $context, $domain = 'default') {
 350      $translations = yourls_get_translations_for_domain( $domain );
 351      $translation = $translations->translate_plural( $single, $plural, $number, $context );
 352      return yourls_apply_filter( 'translate_nx', $translation, $single, $plural, $number, $context, $domain );
 353  }
 354  
 355  /**
 356   * Register plural strings in POT file, but don't translate them.
 357   *
 358   * Used when you want to keep structures with translatable plural strings and
 359   * use them later.
 360   *
 361   * Example:
 362   *  $messages = array(
 363   *      'post' => yourls_n_noop('%s post', '%s posts'),
 364   *      'page' => yourls_n_noop('%s pages', '%s pages')
 365   *  );
 366   *  ...
 367   *  $message = $messages[$type];
 368   *  $usable_text = sprintf( yourls_translate_nooped_plural( $message, $count ), $count );
 369   *
 370   * @since 1.6
 371   * @param string $singular Single form to be i18ned
 372   * @param string $plural Plural form to be i18ned
 373   * @param string $domain Optional. The domain identifier the text will be retrieved in
 374   * @return array array($singular, $plural)
 375   */
 376  function yourls_n_noop( $singular, $plural, $domain = null ) {
 377      return array(
 378          0 => $singular,
 379          1 => $plural,
 380          'singular' => $singular,
 381          'plural' => $plural,
 382          'context' => null,
 383          'domain' => $domain
 384      );
 385  }
 386  
 387  /**
 388   * Register plural strings with context in POT file, but don't translate them.
 389   *
 390   * @since 1.6
 391   * @see yourls_n_noop()
 392   *
 393   * @param string $singular Single form to be i18ned
 394   * @param string $plural   Plural form to be i18ned
 395   * @param string $context  Context information for the translators
 396   * @param string $domain   Optional. The domain identifier the text will be retrieved in
 397   * @return array           array($singular, $plural)
 398   */
 399  function yourls_nx_noop( $singular, $plural, $context, $domain = null ) {
 400      return array(
 401          0 => $singular,
 402          1 => $plural,
 403          2 => $context,
 404          'singular' => $singular,
 405          'plural' => $plural,
 406          'context' => $context,
 407          'domain' => $domain
 408      );
 409  }
 410  
 411  /**
 412   * Translate the result of yourls_n_noop() or yourls_nx_noop()
 413   *
 414   * @since 1.6
 415   * @param array $nooped_plural Array with singular, plural and context keys, usually the result of yourls_n_noop() or yourls_nx_noop()
 416   * @param int $count Number of objects
 417   * @param string $domain Optional. The domain identifier the text should be retrieved in. If $nooped_plural contains
 418   *     a domain passed to yourls_n_noop() or yourls_nx_noop(), it will override this value.
 419   * @return string
 420   */
 421  function yourls_translate_nooped_plural( $nooped_plural, $count, $domain = 'default' ) {
 422      if ( $nooped_plural['domain'] )
 423          $domain = $nooped_plural['domain'];
 424  
 425      if ( $nooped_plural['context'] )
 426          return yourls_nx( $nooped_plural['singular'], $nooped_plural['plural'], $count, $nooped_plural['context'], $domain );
 427      else
 428          return yourls_n( $nooped_plural['singular'], $nooped_plural['plural'], $count, $domain );
 429  }
 430  
 431  /**
 432   * Loads a MO file into the domain $domain.
 433   *
 434   * If the domain already exists, the translations will be merged. If both
 435   * sets have the same string, the translation from the original value will be taken.
 436   *
 437   * On success, the .mo file will be placed in the $yourls_l10n global by $domain
 438   * and will be a MO object.
 439   *
 440   * @since 1.6
 441   *
 442   * @param string $domain Unique identifier for retrieving translated strings
 443   * @param string $mofile Path to the .mo file
 444   * @return bool True on success, false on failure
 445   */
 446  function yourls_load_textdomain( $domain, $mofile ) {
 447      global $yourls_l10n;
 448  
 449      $plugin_override = yourls_apply_filter( 'override_load_textdomain', false, $domain, $mofile );
 450  
 451      if ( true == $plugin_override ) {
 452          return true;
 453      }
 454  
 455      yourls_do_action( 'load_textdomain', $domain, $mofile );
 456  
 457      $mofile = yourls_apply_filter( 'load_textdomain_mofile', $mofile, $domain );
 458  
 459      if ( !is_readable( $mofile ) ) {
 460          trigger_error( 'Cannot read file ' . str_replace( YOURLS_ABSPATH.'/', '', $mofile ) . '.'
 461                      . ' Make sure there is a language file installed. More info: http://yourls.org/translations' );
 462          return false;
 463      }
 464  
 465      $mo = new MO();
 466      if ( !$mo->import_from_file( $mofile ) )
 467          return false;
 468  
 469      if ( isset( $yourls_l10n[$domain] ) )
 470          $mo->merge_with( $yourls_l10n[$domain] );
 471  
 472      $yourls_l10n[$domain] = &$mo;
 473  
 474      return true;
 475  }
 476  
 477  /**
 478   * Unloads translations for a domain
 479   *
 480   * @since 1.6
 481   * @param string $domain Textdomain to be unloaded
 482   * @return bool Whether textdomain was unloaded
 483   */
 484  function yourls_unload_textdomain( $domain ) {
 485      global $yourls_l10n;
 486  
 487      $plugin_override = yourls_apply_filter( 'override_unload_textdomain', false, $domain );
 488  
 489      if ( $plugin_override )
 490          return true;
 491  
 492      yourls_do_action( 'unload_textdomain', $domain );
 493  
 494      if ( isset( $yourls_l10n[$domain] ) ) {
 495          unset( $yourls_l10n[$domain] );
 496          return true;
 497      }
 498  
 499      return false;
 500  }
 501  
 502  /**
 503   * Loads default translated strings based on locale.
 504   *
 505   * Loads the .mo file in YOURLS_LANG_DIR constant path from YOURLS root. The
 506   * translated (.mo) file is named based on the locale.
 507   *
 508   * @since 1.6
 509   * @return bool True on success, false on failure
 510   */
 511  function yourls_load_default_textdomain() {
 512      $yourls_locale = yourls_get_locale();
 513  
 514      if( !empty( $yourls_locale ) )
 515          return yourls_load_textdomain( 'default', YOURLS_LANG_DIR . "/$yourls_locale.mo" );
 516  
 517      return false;
 518  }
 519  
 520  /**
 521   * Returns the Translations instance for a domain. If there isn't one,
 522   * returns empty Translations instance.
 523   *
 524   * @param string $domain
 525   * @return NOOPTranslations An NOOPTranslations translation instance
 526   */
 527  function yourls_get_translations_for_domain( $domain ) {
 528      global $yourls_l10n;
 529      if ( !isset( $yourls_l10n[$domain] ) ) {
 530          $yourls_l10n[$domain] = new NOOPTranslations;
 531      }
 532      return $yourls_l10n[$domain];
 533  }
 534  
 535  /**
 536   * Whether there are translations for the domain
 537   *
 538   * @since 1.6
 539   * @param string $domain
 540   * @return bool Whether there are translations
 541   */
 542  function yourls_is_textdomain_loaded( $domain ) {
 543      global $yourls_l10n;
 544      return isset( $yourls_l10n[$domain] );
 545  }
 546  
 547  /**
 548   * Translates role name. Unused.
 549   *
 550   * Unused function for the moment, we'll see when there are roles.
 551   * From the WP source: Since the role names are in the database and
 552   * not in the source there are dummy gettext calls to get them into the POT
 553   * file and this function properly translates them back.
 554   *
 555   * @since 1.6
 556   * @param string $name The role name
 557   * @return string Translated role name
 558   */
 559  function yourls_translate_user_role( $name ) {
 560      return yourls_translate_with_context( $name, 'User role' );
 561  }
 562  
 563  /**
 564   * Get all available languages (*.mo files) in a given directory. The default directory is YOURLS_LANG_DIR.
 565   *
 566   * @since 1.6
 567   *
 568   * @param string $dir A directory in which to search for language files. The default directory is YOURLS_LANG_DIR.
 569   * @return array Array of language codes or an empty array if no languages are present. Language codes are formed by stripping the .mo extension from the language file names.
 570   */
 571  function yourls_get_available_languages( $dir = null ) {
 572      $languages = array();
 573  
 574      $dir = is_null( $dir) ? YOURLS_LANG_DIR : $dir;
 575  
 576      foreach( (array) glob( $dir . '/*.mo' ) as $lang_file ) {
 577          $languages[] = basename( $lang_file, '.mo' );
 578      }
 579  
 580      return yourls_apply_filter( 'get_available_languages', $languages );
 581  }
 582  
 583  /**
 584   * Return integer number to format based on the locale.
 585   *
 586   * @since 1.6
 587   *
 588   * @param int $number The number to convert based on locale.
 589   * @param int $decimals Precision of the number of decimal places.
 590   * @return string Converted number in string format.
 591   */
 592  function yourls_number_format_i18n( $number, $decimals = 0 ) {
 593      global $yourls_locale_formats;
 594      if( !isset( $yourls_locale_formats ) )
 595          $yourls_locale_formats = new YOURLS_Locale_Formats();
 596  
 597      $formatted = number_format( $number, abs( intval( $decimals ) ), $yourls_locale_formats->number_format['decimal_point'], $yourls_locale_formats->number_format['thousands_sep'] );
 598      return yourls_apply_filter( 'number_format_i18n', $formatted );
 599  }
 600  
 601  /**
 602   * Return the date in localized format, based on timestamp.
 603   *
 604   * If the locale specifies the locale month and weekday, then the locale will
 605   * take over the format for the date. If it isn't, then the date format string
 606   * will be used instead.
 607   *
 608   * @since 1.6
 609   *
 610   * @param  string   $dateformatstring   Format to display the date.
 611   * @param  bool|int $timestamp          Optional, Unix timestamp, default to current timestamp (with offset if applicable)
 612   * @return string                       The date, translated if locale specifies it.
 613   */
 614  function yourls_date_i18n( $dateformatstring, $timestamp = false ) {
 615      /**
 616       * @var YOURLS_Locale_Formats $yourls_locale_formats
 617       */
 618      global $yourls_locale_formats;
 619      if( !isset( $yourls_locale_formats ) )
 620          $yourls_locale_formats = new YOURLS_Locale_Formats();
 621  
 622      if ( false === $timestamp ) {
 623          $timestamp = yourls_get_timestamp( time() );
 624      }
 625  
 626      // store original value for language with untypical grammars
 627      $req_format = $dateformatstring;
 628  
 629      /**
 630       * Replace the date format characters with their translatation, if found
 631       * Example:
 632       *     'l d F Y' gets replaced with '\L\u\n\d\i d \M\a\i Y' in French
 633       * We deliberately don't deal with 'I', 'O', 'P', 'T', 'Z' and 'e' in date format (timezones)
 634       */
 635      if ( ( !empty( $yourls_locale_formats->month ) ) && ( !empty( $yourls_locale_formats->weekday ) ) ) {
 636          $datemonth            = $yourls_locale_formats->get_month( date( 'm', $timestamp ) );
 637          $datemonth_abbrev     = $yourls_locale_formats->get_month_abbrev( $datemonth );
 638          $dateweekday          = $yourls_locale_formats->get_weekday( date( 'w', $timestamp ) );
 639          $dateweekday_abbrev   = $yourls_locale_formats->get_weekday_abbrev( $dateweekday );
 640          $datemeridiem         = $yourls_locale_formats->get_meridiem( date( 'a', $timestamp ) );
 641          $datemeridiem_capital = $yourls_locale_formats->get_meridiem( date( 'A', $timestamp ) );
 642  
 643          $dateformatstring = ' '.$dateformatstring;
 644          $dateformatstring = preg_replace( "/([^\\\])D/", "\\1" . yourls_backslashit( $dateweekday_abbrev ), $dateformatstring );
 645          $dateformatstring = preg_replace( "/([^\\\])F/", "\\1" . yourls_backslashit( $datemonth ), $dateformatstring );
 646          $dateformatstring = preg_replace( "/([^\\\])l/", "\\1" . yourls_backslashit( $dateweekday ), $dateformatstring );
 647          $dateformatstring = preg_replace( "/([^\\\])M/", "\\1" . yourls_backslashit( $datemonth_abbrev ), $dateformatstring );
 648          $dateformatstring = preg_replace( "/([^\\\])a/", "\\1" . yourls_backslashit( $datemeridiem ), $dateformatstring );
 649          $dateformatstring = preg_replace( "/([^\\\])A/", "\\1" . yourls_backslashit( $datemeridiem_capital ), $dateformatstring );
 650  
 651          $dateformatstring = substr( $dateformatstring, 1, strlen( $dateformatstring ) -1 );
 652      }
 653  
 654      $date = date( $dateformatstring, $timestamp );
 655  
 656      // Allow plugins to redo this entirely for languages with untypical grammars
 657      return yourls_apply_filter('date_i18n', $date, $req_format, $timestamp);
 658  }
 659  
 660  /**
 661   * Class that loads the calendar locale.
 662   *
 663   * @since 1.6
 664   */
 665  class YOURLS_Locale_Formats {
 666      /**
 667       * Stores the translated strings for the full weekday names.
 668       *
 669       * @since 1.6
 670       * @var array
 671       * @access private
 672       */
 673      var $weekday;
 674  
 675      /**
 676       * Stores the translated strings for the one character weekday names.
 677       *
 678       * There is a hack to make sure that Tuesday and Thursday, as well
 679       * as Sunday and Saturday, don't conflict. See init() method for more.
 680       *
 681       * @see YOURLS_Locale_Formats::init() for how to handle the hack.
 682       *
 683       * @since 1.6
 684       * @var array
 685       * @access private
 686       */
 687      var $weekday_initial;
 688  
 689      /**
 690       * Stores the translated strings for the abbreviated weekday names.
 691       *
 692       * @since 1.6
 693       * @var array
 694       * @access private
 695       */
 696      var $weekday_abbrev;
 697  
 698      /**
 699       * Stores the translated strings for the full month names.
 700       *
 701       * @since 1.6
 702       * @var array
 703       * @access private
 704       */
 705      var $month;
 706  
 707      /**
 708       * Stores the translated strings for the abbreviated month names.
 709       *
 710       * @since 1.6
 711       * @var array
 712       * @access private
 713       */
 714      var $month_abbrev;
 715  
 716      /**
 717       * Stores the translated strings for 'am' and 'pm'.
 718       *
 719       * Also the capitalized versions.
 720       *
 721       * @since 1.6
 722       * @var array
 723       * @access private
 724       */
 725      var $meridiem;
 726  
 727      /**
 728       * Stores the translated number format
 729       *
 730       * @since 1.6
 731       * @var array
 732       * @access private
 733       */
 734      var $number_format;
 735  
 736      /**
 737       * The text direction of the locale language.
 738       *
 739       * Default is left to right 'ltr'.
 740       *
 741       * @since 1.6
 742       * @var string
 743       * @access private
 744       */
 745      var $text_direction = 'ltr';
 746  
 747      /**
 748       * Sets up the translated strings and object properties.
 749       *
 750       * The method creates the translatable strings for various
 751       * calendar elements. Which allows for specifying locale
 752       * specific calendar names and text direction.
 753       *
 754       * @since 1.6
 755       * @access private
 756       * @return void
 757       */
 758      function init() {
 759          // The Weekdays
 760          $this->weekday[0] = /* //translators: weekday */ yourls__( 'Sunday' );
 761          $this->weekday[1] = /* //translators: weekday */ yourls__( 'Monday' );
 762          $this->weekday[2] = /* //translators: weekday */ yourls__( 'Tuesday' );
 763          $this->weekday[3] = /* //translators: weekday */ yourls__( 'Wednesday' );
 764          $this->weekday[4] = /* //translators: weekday */ yourls__( 'Thursday' );
 765          $this->weekday[5] = /* //translators: weekday */ yourls__( 'Friday' );
 766          $this->weekday[6] = /* //translators: weekday */ yourls__( 'Saturday' );
 767  
 768          // The first letter of each day. The _%day%_initial suffix is a hack to make
 769          // sure the day initials are unique.
 770          $this->weekday_initial[yourls__( 'Sunday' )]    = /* //translators: one-letter abbreviation of the weekday */ yourls__( 'S_Sunday_initial' );
 771          $this->weekday_initial[yourls__( 'Monday' )]    = /* //translators: one-letter abbreviation of the weekday */ yourls__( 'M_Monday_initial' );
 772          $this->weekday_initial[yourls__( 'Tuesday' )]   = /* //translators: one-letter abbreviation of the weekday */ yourls__( 'T_Tuesday_initial' );
 773          $this->weekday_initial[yourls__( 'Wednesday' )] = /* //translators: one-letter abbreviation of the weekday */ yourls__( 'W_Wednesday_initial' );
 774          $this->weekday_initial[yourls__( 'Thursday' )]  = /* //translators: one-letter abbreviation of the weekday */ yourls__( 'T_Thursday_initial' );
 775          $this->weekday_initial[yourls__( 'Friday' )]    = /* //translators: one-letter abbreviation of the weekday */ yourls__( 'F_Friday_initial' );
 776          $this->weekday_initial[yourls__( 'Saturday' )]  = /* //translators: one-letter abbreviation of the weekday */ yourls__( 'S_Saturday_initial' );
 777  
 778          foreach ($this->weekday_initial as $weekday_ => $weekday_initial_) {
 779              $this->weekday_initial[$weekday_] = preg_replace('/_.+_initial$/', '', $weekday_initial_);
 780          }
 781  
 782          // Abbreviations for each day.
 783          $this->weekday_abbrev[ yourls__( 'Sunday' ) ]    = /* //translators: three-letter abbreviation of the weekday */ yourls__( 'Sun' );
 784          $this->weekday_abbrev[ yourls__( 'Monday' ) ]    = /* //translators: three-letter abbreviation of the weekday */ yourls__( 'Mon' );
 785          $this->weekday_abbrev[ yourls__( 'Tuesday' ) ]   = /* //translators: three-letter abbreviation of the weekday */ yourls__( 'Tue' );
 786          $this->weekday_abbrev[ yourls__( 'Wednesday' ) ] = /* //translators: three-letter abbreviation of the weekday */ yourls__( 'Wed' );
 787          $this->weekday_abbrev[ yourls__( 'Thursday' ) ]  = /* //translators: three-letter abbreviation of the weekday */ yourls__( 'Thu' );
 788          $this->weekday_abbrev[ yourls__( 'Friday' ) ]    = /* //translators: three-letter abbreviation of the weekday */ yourls__( 'Fri' );
 789          $this->weekday_abbrev[ yourls__( 'Saturday' ) ]  = /* //translators: three-letter abbreviation of the weekday */ yourls__( 'Sat' );
 790  
 791          // The Months
 792          $this->month['01'] = /* //translators: month name */ yourls__( 'January' );
 793          $this->month['02'] = /* //translators: month name */ yourls__( 'February' );
 794          $this->month['03'] = /* //translators: month name */ yourls__( 'March' );
 795          $this->month['04'] = /* //translators: month name */ yourls__( 'April' );
 796          $this->month['05'] = /* //translators: month name */ yourls__( 'May' );
 797          $this->month['06'] = /* //translators: month name */ yourls__( 'June' );
 798          $this->month['07'] = /* //translators: month name */ yourls__( 'July' );
 799          $this->month['08'] = /* //translators: month name */ yourls__( 'August' );
 800          $this->month['09'] = /* //translators: month name */ yourls__( 'September' );
 801          $this->month['10'] = /* //translators: month name */ yourls__( 'October' );
 802          $this->month['11'] = /* //translators: month name */ yourls__( 'November' );
 803          $this->month['12'] = /* //translators: month name */ yourls__( 'December' );
 804  
 805          // Abbreviations for each month. Uses the same hack as above to get around the
 806          // 'May' duplication.
 807          $this->month_abbrev[ yourls__( 'January' ) ]   = /* //translators: three-letter abbreviation of the month */ yourls__( 'Jan_January_abbreviation' );
 808          $this->month_abbrev[ yourls__( 'February' ) ]  = /* //translators: three-letter abbreviation of the month */ yourls__( 'Feb_February_abbreviation' );
 809          $this->month_abbrev[ yourls__( 'March' ) ]     = /* //translators: three-letter abbreviation of the month */ yourls__( 'Mar_March_abbreviation' );
 810          $this->month_abbrev[ yourls__( 'April' ) ]     = /* //translators: three-letter abbreviation of the month */ yourls__( 'Apr_April_abbreviation' );
 811          $this->month_abbrev[ yourls__( 'May' ) ]       = /* //translators: three-letter abbreviation of the month */ yourls__( 'May_May_abbreviation' );
 812          $this->month_abbrev[ yourls__( 'June' ) ]      = /* //translators: three-letter abbreviation of the month */ yourls__( 'Jun_June_abbreviation' );
 813          $this->month_abbrev[ yourls__( 'July' ) ]      = /* //translators: three-letter abbreviation of the month */ yourls__( 'Jul_July_abbreviation' );
 814          $this->month_abbrev[ yourls__( 'August' ) ]    = /* //translators: three-letter abbreviation of the month */ yourls__( 'Aug_August_abbreviation' );
 815          $this->month_abbrev[ yourls__( 'September' ) ] = /* //translators: three-letter abbreviation of the month */ yourls__( 'Sep_September_abbreviation' );
 816          $this->month_abbrev[ yourls__( 'October' ) ]   = /* //translators: three-letter abbreviation of the month */ yourls__( 'Oct_October_abbreviation' );
 817          $this->month_abbrev[ yourls__( 'November' ) ]  = /* //translators: three-letter abbreviation of the month */ yourls__( 'Nov_November_abbreviation' );
 818          $this->month_abbrev[ yourls__( 'December' ) ]  = /* //translators: three-letter abbreviation of the month */ yourls__( 'Dec_December_abbreviation' );
 819  
 820          foreach ($this->month_abbrev as $month_ => $month_abbrev_) {
 821              $this->month_abbrev[$month_] = preg_replace('/_.+_abbreviation$/', '', $month_abbrev_);
 822          }
 823  
 824          // The Meridiems
 825          $this->meridiem['am'] = yourls__( 'am' );
 826          $this->meridiem['pm'] = yourls__( 'pm' );
 827          $this->meridiem['AM'] = yourls__( 'AM' );
 828          $this->meridiem['PM'] = yourls__( 'PM' );
 829  
 830          // Numbers formatting
 831          // See http://php.net/number_format
 832  
 833          /* //translators: $thousands_sep argument for http://php.net/number_format, default is , */
 834          $trans = yourls__( 'number_format_thousands_sep' );
 835          $this->number_format['thousands_sep'] = ('number_format_thousands_sep' == $trans) ? ',' : $trans;
 836  
 837          /* //translators: $dec_point argument for http://php.net/number_format, default is . */
 838          $trans = yourls__( 'number_format_decimal_point' );
 839          $this->number_format['decimal_point'] = ('number_format_decimal_point' == $trans) ? '.' : $trans;
 840  
 841          // Set text direction.
 842          if ( isset( $GLOBALS['text_direction'] ) )
 843              $this->text_direction = $GLOBALS['text_direction'];
 844          /* //translators: 'rtl' or 'ltr'. This sets the text direction for YOURLS. */
 845          elseif ( 'rtl' == yourls_x( 'ltr', 'text direction' ) )
 846              $this->text_direction = 'rtl';
 847      }
 848  
 849      /**
 850       * Retrieve the full translated weekday word.
 851       *
 852       * Week starts on translated Sunday and can be fetched
 853       * by using 0 (zero). So the week starts with 0 (zero)
 854       * and ends on Saturday with is fetched by using 6 (six).
 855       *
 856       * @since 1.6
 857       * @access public
 858       *
 859       * @param int|string $weekday_number 0 for Sunday through 6 Saturday
 860       * @return string Full translated weekday
 861       */
 862      function get_weekday( $weekday_number ) {
 863          return $this->weekday[ $weekday_number ];
 864      }
 865  
 866      /**
 867       * Retrieve the translated weekday initial.
 868       *
 869       * The weekday initial is retrieved by the translated
 870       * full weekday word. When translating the weekday initial
 871       * pay attention to make sure that the starting letter does
 872       * not conflict.
 873       *
 874       * @since 1.6
 875       * @access public
 876       *
 877       * @param string $weekday_name
 878       * @return string
 879       */
 880      function get_weekday_initial( $weekday_name ) {
 881          return $this->weekday_initial[ $weekday_name ];
 882      }
 883  
 884      /**
 885       * Retrieve the translated weekday abbreviation.
 886       *
 887       * The weekday abbreviation is retrieved by the translated
 888       * full weekday word.
 889       *
 890       * @since 1.6
 891       * @access public
 892       *
 893       * @param string $weekday_name Full translated weekday word
 894       * @return string Translated weekday abbreviation
 895       */
 896      function get_weekday_abbrev( $weekday_name ) {
 897          return $this->weekday_abbrev[ $weekday_name ];
 898      }
 899  
 900      /**
 901       * Retrieve the full translated month by month number.
 902       *
 903       * The $month_number parameter has to be a string
 904       * because it must have the '0' in front of any number
 905       * that is less than 10. Starts from '01' and ends at
 906       * '12'.
 907       *
 908       * You can use an integer instead and it will add the
 909       * '0' before the numbers less than 10 for you.
 910       *
 911       * @since 1.6
 912       * @access public
 913       *
 914       * @param string|int $month_number '01' through '12'
 915       * @return string Translated full month name
 916       */
 917      function get_month( $month_number ) {
 918          return $this->month[ sprintf( '%02s', $month_number ) ];
 919      }
 920  
 921      /**
 922       * Retrieve translated version of month abbreviation string.
 923       *
 924       * The $month_name parameter is expected to be the translated or
 925       * translatable version of the month.
 926       *
 927       * @since 1.6
 928       * @access public
 929       *
 930       * @param string $month_name Translated month to get abbreviated version
 931       * @return string Translated abbreviated month
 932       */
 933      function get_month_abbrev( $month_name ) {
 934          return $this->month_abbrev[ $month_name ];
 935      }
 936  
 937      /**
 938       * Retrieve translated version of meridiem string.
 939       *
 940       * The $meridiem parameter is expected to not be translated.
 941       *
 942       * @since 1.6
 943       * @access public
 944       *
 945       * @param string $meridiem Either 'am', 'pm', 'AM', or 'PM'. Not translated version.
 946       * @return string Translated version
 947       */
 948      function get_meridiem( $meridiem ) {
 949          return $this->meridiem[ $meridiem ];
 950      }
 951  
 952      /**
 953       * Global variables are deprecated. For backwards compatibility only.
 954       *
 955       * @deprecated For backwards compatibility only.
 956       * @access private
 957       *
 958       * @since 1.6
 959       * @return void
 960       */
 961      function register_globals() {
 962          $GLOBALS['weekday']         = $this->weekday;
 963          $GLOBALS['weekday_initial'] = $this->weekday_initial;
 964          $GLOBALS['weekday_abbrev']  = $this->weekday_abbrev;
 965          $GLOBALS['month']           = $this->month;
 966          $GLOBALS['month_abbrev']    = $this->month_abbrev;
 967      }
 968  
 969      /**
 970       * Constructor which calls helper methods to set up object variables
 971       *
 972       * @since 1.6
 973       */
 974      function __construct() {
 975          $this->init();
 976          $this->register_globals();
 977      }
 978  
 979      /**
 980       * Checks if current locale is RTL.
 981       *
 982       * @since 1.6
 983       * @return bool Whether locale is RTL.
 984       */
 985      function is_rtl() {
 986          return 'rtl' == $this->text_direction;
 987      }
 988  }
 989  
 990  /**
 991   * Loads a custom translation file (for a plugin, a theme, a public interface...) if locale is defined
 992   *
 993   * The .mo file should be named based on the domain with a dash, and then the locale exactly,
 994   * eg 'myplugin-pt_BR.mo'
 995   *
 996   * @since 1.6
 997   *
 998   * @param string $domain Unique identifier (the "domain") for retrieving translated strings
 999   * @param string $path Full path to directory containing MO files.
1000   * @return mixed|void Returns nothing if locale undefined, otherwise return bool: true on success, false on failure
1001   */
1002  function yourls_load_custom_textdomain( $domain, $path ) {
1003      $locale = yourls_apply_filter( 'load_custom_textdomain', yourls_get_locale(), $domain );
1004      if( !empty( $locale ) ) {
1005          $mofile = rtrim( $path, '/' ) . '/'. $domain . '-' . $locale . '.mo';
1006          return yourls_load_textdomain( $domain, $mofile );
1007      }
1008  }
1009  
1010  /**
1011   * Checks if current locale is RTL. Stolen from WP.
1012   *
1013   * @since 1.6
1014   * @return bool Whether locale is RTL.
1015   */
1016  function yourls_is_rtl() {
1017      global $yourls_locale_formats;
1018      if( !isset( $yourls_locale_formats ) )
1019          $yourls_locale_formats = new YOURLS_Locale_Formats();
1020  
1021      return $yourls_locale_formats->is_rtl();
1022  }
1023  
1024  /**
1025   * Return translated weekday abbreviation (3 letters, eg 'Fri' for 'Friday')
1026   *
1027   * The $weekday var can be a textual string ('Friday'), a integer (0 to 6) or an empty string
1028   * If $weekday is an empty string, the function returns an array of all translated weekday abbrev
1029   *
1030   * @since 1.6
1031   * @param mixed $weekday A full textual weekday, eg "Friday", or an integer (0 = Sunday, 1 = Monday, .. 6 = Saturday)
1032   * @return mixed Translated weekday abbreviation, eg "Ven" (abbrev of "Vendredi") for "Friday" or 5, or array of all weekday abbrev
1033   */
1034  function yourls_l10n_weekday_abbrev( $weekday = '' ){
1035      global $yourls_locale_formats;
1036      if( !isset( $yourls_locale_formats ) )
1037          $yourls_locale_formats = new YOURLS_Locale_Formats();
1038  
1039      if( $weekday === '' )
1040          return $yourls_locale_formats->weekday_abbrev;
1041  
1042      if( is_int( $weekday ) ) {
1043          $day = $yourls_locale_formats->weekday[ $weekday ];
1044          return $yourls_locale_formats->weekday_abbrev[ $day ];
1045      } else {
1046          return $yourls_locale_formats->weekday_abbrev[ yourls__( $weekday ) ];
1047      }
1048  }
1049  
1050  /**
1051   * Return translated weekday initial (1 letter, eg 'F' for 'Friday')
1052   *
1053   * The $weekday var can be a textual string ('Friday'), a integer (0 to 6) or an empty string
1054   * If $weekday is an empty string, the function returns an array of all translated weekday initials
1055   *
1056   * @since 1.6
1057   * @param mixed $weekday A full textual weekday, eg "Friday", an integer (0 = Sunday, 1 = Monday, .. 6 = Saturday) or empty string
1058   * @return mixed Translated weekday initial, eg "V" (initial of "Vendredi") for "Friday" or 5, or array of all weekday initials
1059   */
1060  function yourls_l10n_weekday_initial( $weekday = '' ){
1061      global $yourls_locale_formats;
1062      if( !isset( $yourls_locale_formats ) )
1063          $yourls_locale_formats = new YOURLS_Locale_Formats();
1064  
1065      if( $weekday === '' )
1066          return $yourls_locale_formats->weekday_initial;
1067  
1068      if( is_int( $weekday ) ) {
1069          $weekday = $yourls_locale_formats->weekday[ $weekday ];
1070          return $yourls_locale_formats->weekday_initial[ $weekday ];
1071      } else {
1072          return $yourls_locale_formats->weekday_initial[ yourls__( $weekday ) ];
1073      }
1074  }
1075  
1076  /**
1077   * Return translated month abbrevation (3 letters, eg 'Nov' for 'November')
1078   *
1079   * The $month var can be a textual string ('November'), a integer (1 to 12), a two digits strings ('01' to '12), or an empty string
1080   * If $month is an empty string, the function returns an array of all translated abbrev months ('January' => 'Jan', ...)
1081   *
1082   * @since 1.6
1083   * @param mixed $month Empty string, a full textual weekday, eg "November", or an integer (1 = January, .., 12 = December)
1084   * @return mixed Translated month abbrev (eg "Nov"), or array of all translated abbrev months
1085   */
1086  function yourls_l10n_month_abbrev( $month = '' ){
1087      global $yourls_locale_formats;
1088      if( !isset( $yourls_locale_formats ) )
1089          $yourls_locale_formats = new YOURLS_Locale_Formats();
1090  
1091      if( $month === '' )
1092          return $yourls_locale_formats->month_abbrev;
1093  
1094      if( intval( $month ) > 0 ) {
1095          $month = sprintf('%02d', intval( $month ) );
1096          $month = $yourls_locale_formats->month[ $month ];
1097          return $yourls_locale_formats->month_abbrev[ $month ];
1098      } else {
1099          return $yourls_locale_formats->month_abbrev[ yourls__( $month ) ];
1100      }
1101  }
1102  
1103  /**
1104   * Return array of all translated months
1105   *
1106   * @since 1.6
1107   * @return array Array of all translated months
1108   */
1109  function yourls_l10n_months(){
1110      global $yourls_locale_formats;
1111      if( !isset( $yourls_locale_formats ) )
1112          $yourls_locale_formats = new YOURLS_Locale_Formats();
1113  
1114      return $yourls_locale_formats->month;
1115  }


Generated: Tue Jan 27 05:10:15 2026 Cross-referenced by PHPXref 0.7.1