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