[ Index ]

PHP Cross Reference of GlotPress

title

Body

[close]

/gp-includes/ -> warnings.php (source)

   1  <?php
   2  /**
   3   * Handles translation warnings
   4   */
   5  
   6  class GP_Translation_Warnings {
   7      var $callbacks = array();
   8  
   9  	function add( $id, $callback ) {
  10          $this->callbacks[$id] = $callback;
  11      }
  12      
  13  	function remove( $id ) {
  14          unset( $this->callbacks[$id] );
  15      }
  16      
  17  	function has( $id ) {
  18          return isset( $this->callbacks[$id] );
  19      }
  20      
  21  	function check( $singular, $plural, $translations, $locale ) {
  22          $problems = array();
  23          foreach( $translations as $translation_index => $translation ) {
  24              if ( !$translation ) continue;
  25              $skip = array( 'singular' => false, 'plural' => false );
  26              if ( !is_null( $plural ) ) {
  27                  $numbers_for_index = $locale->numbers_for_index( $translation_index );
  28                  if ( $numbers_for_index == array(1) ) {
  29                      $skip['plural'] = true;
  30                  }
  31                  if ( !in_array( 1, $numbers_for_index ) ) {
  32                      $skip['singular'] = true;
  33                  }
  34                  if ( $locale->nplurals == 1 ) {
  35                      $skip['singular'] = true;
  36                  }
  37              }
  38              foreach( $this->callbacks as $callback_id => $callback ) {
  39                  if ( !$skip['singular']) {
  40                      $singular_test = call_user_func( $callback, $singular, $translation, $locale );
  41                      if ( true !== $singular_test ) {
  42                          $problems[$translation_index][$callback_id] = $singular_test;
  43                      }
  44                  }
  45                  if ( !is_null( $plural ) && !$skip['plural'] ) {
  46                      $plural_test = call_user_func( $callback, $plural, $translation, $locale );
  47                      if ( true !== $plural_test ) {
  48                          $problems[$translation_index][$callback_id] = $plural_test;
  49                      }
  50                  }
  51              }
  52          }
  53          return empty($problems)? null : $problems;
  54      }
  55  }
  56  
  57  class GP_Builtin_Translation_Warnings {
  58      
  59      var $length_lower_bound = 0.2;
  60      var $length_upper_bound = 5.0;
  61      var $length_exclude_languages = array('ja', 'zh', 'zh-hk', 'zh-cn', 'zh-sg', 'zh-tw');
  62      
  63  	function warning_length( $original, $translation, $locale ) {
  64          if ( in_array( $locale->slug, $this->length_exclude_languages ) ) {
  65              return true;
  66          }
  67          if ( gp_startswith( $original, 'number_format_' ) ) {
  68              return true;
  69          }
  70          $len_src = gp_strlen( $original );
  71          $len_trans = gp_strlen( $translation );
  72          if ( !( $this->length_lower_bound*$len_src < $len_trans && $len_trans < $this->length_upper_bound*$len_src ) &&
  73                  ( !gp_in( '_abbreviation', $original ) && !gp_in( '_initial', $original ) ) ) {
  74              return __('Lengths of source and translation differ too much.');
  75          }
  76          return true;
  77      }
  78      
  79  	function warning_tags( $original, $translation, $locale ) {
  80          $tag_pattern = "(<[^>]*>)";
  81          $tag_re = "/$tag_pattern/Us";
  82          $original_parts = preg_split($tag_re, $original, -1, PREG_SPLIT_DELIM_CAPTURE);
  83          $translation_parts = preg_split($tag_re, $translation, -1, PREG_SPLIT_DELIM_CAPTURE);
  84          if ( count( $original_parts) > count( $translation_parts ) ) {
  85              return __('Missing tags from translation.');
  86          }
  87          if ( count( $original_parts) < count( $translation_parts ) ) {
  88              return __('Too many tags in translation.');
  89          }
  90          foreach( gp_array_zip( $original_parts, $translation_parts ) as $tags ) {
  91              list( $original_tag, $translation_tag ) = $tags;
  92              $expected_error_msg = "Expected $original_tag, got $translation_tag.";
  93              $original_is_tag = preg_match( "/^$tag_pattern$/", $original_tag );
  94              $translation_is_tag = preg_match( "/^$tag_pattern$/", $translation_tag );
  95              // translations should never need a quote in their title attribute 
  96              if ( $original_is_tag && $translation_is_tag && $original_tag != $translation_tag ) {
  97                  // we allow translations to have a different title tag
  98                  $title_re_single = '\s*title=\'[^\']+\'\s*';
  99                  $title_re = '%'.$title_re_single.'|'.str_replace( "'", '"', $title_re_single ).'%';
 100                  $original_tag = preg_replace( $title_re, '', $original_tag );
 101                  $translation_tag = preg_replace( $title_re, '', $translation_tag );
 102                  if ( $original_tag != $translation_tag ) {
 103                      return $expected_error_msg;
 104                  }
 105              }
 106          }
 107          return true;
 108      }
 109      
 110  	function warning_placeholders( $original, $translation, $locale ) {
 111          $placeholders_re = apply_filters( 'warning_placeholders_re', '%[a-z]*|%[A-Z]+|%\d+\$(?:s|d)' );
 112  
 113          $original_counts = $this->_placeholders_counts( $original, $placeholders_re );
 114          $translation_counts = $this->_placeholders_counts( $translation, $placeholders_re );
 115          $all_placeholders = array_unique( array_merge( array_keys( $original_counts ), array_keys( $translation_counts ) ) );
 116          foreach( $all_placeholders as $placeholder ) {
 117              $original_count = gp_array_get( $original_counts, $placeholder, 0 );
 118              $translation_count = gp_array_get( $translation_counts, $placeholder, 0 );
 119              if ( $original_count > $translation_count ) {
 120                  return sprintf(__('Missing %s placeholder in translation.'), $placeholder);
 121              }
 122              if ( $original_count < $translation_count ) {
 123                  return sprintf(__('Extra %s placeholder in translation.'), $placeholder);
 124              }
 125          }
 126          return true;
 127      }
 128      
 129  	function _placeholders_counts( $string, $re ) {
 130          $counts = array();
 131          preg_match_all( "/$re/", $string, $matches );
 132          foreach( $matches[0] as $match ) {
 133              $counts[$match] = gp_array_get( $counts, $match, 0) + 1;
 134          }
 135          return $counts;
 136      }
 137      
 138  	function warning_both_begin_end_on_newlines( $original, $translation, $locale ) {
 139          if ( gp_endswith( $original, "\n" ) xor gp_endswith( $translation, "\n" ) ) {
 140              return __('Original and translation should both end on newline.');
 141          }
 142          if ( gp_startswith( $original, "\n" ) xor gp_startswith( $translation, "\n" ) ) {
 143              return __('Original and translation should both begin on newline.');
 144          }
 145          return true;
 146      }
 147      
 148      /**
 149       * Adds all methods starting with warning_ to $translation_warnings
 150       */
 151  	function add_all( &$translation_warnings ) {
 152          $warnigs = array_filter( get_class_methods( get_class( $this ) ), create_function( '$f', 'return gp_startswith($f, "warning_");' ) );
 153          foreach( $warnigs as $warning ) {
 154              $translation_warnings->add( str_replace( 'warning_', '', $warning ), array( &$this, $warning ) );
 155          }
 156      }
 157  }


Generated: Thu May 24 03:59:35 2012 Hosted by follow the white rabbit.